循环单链表(circular linked list)是一种首尾相连的单链表。将单链表的最后一个结点的指针域由空指针改为指向头结点或第一个结点,整个链表就形成了一个环,我们称这样的单链表为循环单链表。
与单链表相似,循环单链表也可分为带头结点结构和不带头结点结构两种。对于不带头结点的循环单链表,当表不为空时,最后一个结点的指针域指向头结点。如图所示。
对于带头结点的循环单链表,当表为空时,头结点的指针域指头结点本身。如图所示。
已知一个带哨兵结点h的循环单链表中的数据元素含有整数和负数,试编写另一个算法,构造两个循环单链表,使一个单链表中只含正数,另一个循环单链表只含负数。例如创建一个循环单链表{55,106,-29,-203,761,329,-76,432,87},分拆后变成两个循环单链表,一个只含正数,另一个只含负数,即{55,106,761,329,432}和{-29,-203,-76}
在输出循环单链表时要注意判决条件为
while(p->next!=head)
否则就会出现死循环。
main.cpp
#include <iostream>
#include <malloc.h>
#include <stdlib.h>
using namespace std;
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node *next;
}ListNode,*LinkList;
LinkList CreateCycList();
void Split(LinkList ha, LinkList hb);
void DispCycList(LinkList head);
void main()
{
LinkList ha, hb = NULL;
ListNode *s, *p;
ha = CreateCycList();
p = ha;
while (p->next!=ha)
{
p = p->next;
}
s = (ListNode *)malloc(sizeof(ListNode));
s->next = ha;
ha = s;
p->next = ha;
s = (ListNode*)malloc(sizeof(ListNode));
s->next = hb;
hb = s;
Split(ha, hb);
cout << "输出循环单链表A(正数):" << endl;
DispCycList(ha);
cout << "输出循环单链表B(负数):" << endl;
DispCycList(hb);
system("pause");
}
void Split(LinkList ha, LinkList hb)
{
ListNode *ra, *rb, *p = ha->next;
int v;
ra = ha;
ra->next = NULL;
rb = hb;
rb->next = NULL;
while (p!=ha)
{
v = p->data;
if (v>0)
{
ra->next = p;
ra = p;
}
else
{
rb->next = p;
rb = p;
}
p = p->next;
}
ra->next = ha;
rb->next = hb;
}
LinkList CreateCycList()
{
ListNode *h = NULL, *s, *t = NULL;
DataType e;
int i = 1;
cout << "创建一个循环链表(输入0表示创建链表结束):" << endl;
while (1)
{
cout << "请输入第"<<i<<"个结点的data域值:"<< endl;
scanf("%d", &e);
if (e==0)
{
break;
}
if (i==1)
{
h = (ListNode*)malloc(sizeof(ListNode));
h->data = e;
h->next = NULL;
t = h;
}
else
{
s = (ListNode*)malloc(sizeof(ListNode));
s->data = e;
s->next = NULL;
t->next = s;
t = s;
}
i++;
}
if (t!=NULL)
{
t->next = h;
}
return h;
}
void DispCycList(LinkList h)
{
ListNode *p = h->next;
if (p==NULL)
{
cout << "链表为空!" << endl;
return;
}
while (p->next!=h)
{
cout << p->data << endl;
p = p->next;
}
cout << p->data << endl;
}
结果: