循环链表的优点在于从当前任一个结点起,都可以遍历整个链表,即它的首尾是相连的。
它的定义是:将单链表中的终端结点的指针端由空指针改为头结点,就使整个单链表形成一个环,这种头尾相接的单链表被称为循环链表。
重点代码:
ptail->next=phead;
两个循环链表合并:
ptemp=ptail01->next;
ptail01=ptail02->next->next;
ptail02->next=ptemp;
free(ptemp);
插入代码:
int insert(PNODE pNode,int location,int values)//在第四个位置插入元素的值;
{
PNODE ptemp=(PNODE)malloc(sizeof(NODE));
PNODE p=pNode->next->next;//第一个有效节点
PNODE p1=pNode->next->next;//指向的是链表的头结点
int count=0;//找到插入前的结点的结点位置;
int length=1;//链表长度
while(p1!=pNode->next)
{
p1=p1->next;
length++;
}
while(p!=pNode->next&&count<location-1)
{
p=p->next;
count++;
}
//
if(count>length+1||location<0)
{
return 0;
}
ptemp->data=values;
PNODE q=p->next;
ptemp->next=q;
p->next=ptemp;
return 1;
}
删除:
int deleteNode(PNODE pNode,int pos,int *values)
{
if(pos<0||pos>getlength(pNode))
{
printf("输入的删除元素位置有误!\n");
return 0;
}
PNODE p=pNode->next->next;//第一个有效元素
int count=1;
//查找到一个删除的结点,前一个结点位置;
while(p!=pNode->next&&count<pos-1)
{
p=p->next;
count++;
}
if(count>pos-1||p==pNode->next)
{
return 0;
}
PNODE ptemp=p->next;
*values=ptemp->data;//将删除的元素返回给main函数
p->next=p->next->next;
return 1;
}
整个实现代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
// int length;
}NODE,*PNODE;
PNODE initlist();//初始化元素
int insert(PNODE pNode,int location,int values);//插入结点元素,成功返回1,失败返回0!;
int deleteNode(PNODE phead,int pos,int *values);//删除第pos位置结点的元素值,删除成功返回1,失败返回0!;
int getValues(PNODE phead);//获取结点元素值
int getlength(PNODE pNode);//获取循环链表的长度
void print(PNODE rear);//打印结点
PNODE initlist()
{
PNODE phead=(PNODE)malloc(sizeof(NODE));
if(NULL==phead)
{
printf("动态分配内存失败!\n");
exit(0);
}
// phead->length=0;
phead->data=0;
phead->next=phead;
PNODE ptail=phead;
int i;
int len;
printf("请输入你的链表结点个数:\n");
scanf("%d",&len);
for(i=len;i>0;i--)
{
// scanf("%d",&num);
PNODE ptemp=(PNODE)malloc(sizeof(NODE));
ptemp->data=i*i;
printf("第%d个元素的值为:%d\n",len-i+1,i*i);
ptail->next=ptemp;
ptemp->next=phead;
ptail=ptemp;
// phead->length++;
}
return ptail;
}
int insert(PNODE pNode,int location,int values)//在第四个位置插入元素的值;
{
PNODE ptemp=(PNODE)malloc(sizeof(NODE));
PNODE p=pNode->next->next;//第一个有效节点
PNODE p1=pNode->next->next;//指向的是链表的头结点
int count=0;//找到插入前的结点的结点位置;
int length=1;//链表长度
while(p1!=pNode->next)
{
p1=p1->next;
length++;
}
while(p!=pNode->next&&count<location-1)
{
p=p->next;
count++;
}
//
if(count>length+1||location<0)
{
return 0;
}
ptemp->data=values;
PNODE q=p->next;
ptemp->next=q;
p->next=ptemp;
return 1;
}
int deleteNode(PNODE pNode,int pos,int *values)
{
if(pos<0||pos>getlength(pNode))
{
printf("输入的删除元素位置有误!\n");
return 0;
}
PNODE p=pNode->next->next;//第一个有效元素
int count=1;
//查找到一个删除的结点,前一个结点位置;
while(p!=pNode->next&&count<pos-1)
{
p=p->next;
count++;
}
if(count>pos-1||p==pNode->next)
{
return 0;
}
PNODE ptemp=p->next;
*values=ptemp->data;//将删除的元素返回给main函数
p->next=p->next->next;
return 1;
}
int getlength(PNODE pNode)
{
int length=0;
PNODE ptemp=pNode->next->next;
while(ptemp!=pNode->next)
{
ptemp=ptemp->next;
length++;
}
return length;
}
//如何从尾巴开始打印链表
void print(PNODE rear)
{
PNODE phead=rear->next;
PNODE prear=rear;
int i=0;
printf("从尾节点开始打印数据:\n");
while(1)
{
if(prear==phead)
{
prear=prear->next;
continue;
}
printf("%d ",prear->data);
prear=prear->next;
if(prear==rear)
{
exit(0);
}
}
printf("\n");
return;
}
int main()
{
PNODE pNode;
int location,values;
int pvalues;
pNode=initlist();//此时返回的并不是头结点而是一个尾节点
printf("请输入插入元素位置:\n");
scanf("%d",&location);
printf("元素值为:");
scanf("%d",&values);
int result=insert(pNode,location,values);
if(result==1)
{
printf("插入成功!!\n");
}
else
{
printf("插入失败!\n");
}
int pos=0;
printf("请输入删除元素位置:\n");
scanf("%d",&pos);
int result01=deleteNode(pNode,pos,&pvalues);
if(result01==1)
{
printf("删除成功!!删除元素值:%d\n",pvalues);
}
else
{
printf("删除失败!!\n");
}
print(pNode);
return 0;
}