1.单向循环链表
区分单向链表和单向循环链表:单向循环链表的尾指针指向头结点。
区分单向链表和单向循环链表:单向循环链表的尾指针指向头结点。
2.单向循环链表的基本操作
#include <stdio.h>
#include <malloc.h>
#define NULL 0
typedef struct node {
int data;
struct node *next;
}ElemSN;
ElemSN * creat_link(int ms); //创建一个单向循环链表
void print_link(ElemSN *head); //输出链表
ElemSN * delete_node(ElemSN *head, int x); //删除结点
ElemSN * clear_link(ElemSN *head); //删除链表
int main()
{
ElemSN *head;
int ms, x;
printf("Please input node number:");
scanf("%d", &ms);
head = creat_link(ms); //创建链表
print_link(head);
printf("Please input delete node:");
scanf("%d", &x);
head = delete_node(head, x); //删除结点
print_link(head);
head = clear_link(head); //删除链表
print_link(head);
}
ElemSN * creat_link(int ms) //带表头的单向链表除了头结点其余结点
//创建方法一致,所以不用逆向创建
{
ElemSN *h = NULL, *p;
int i, x;
h = (ElemSN *)malloc(sizeof(ElemSN));
printf("Please input node data:");
scanf("%d", &x);
h->data = x;
h->next = h; //第一个创建完成自己指向自己
for(i=1; i < ms; i++) //正向创建链表
{
p = (ElemSN *)malloc(sizeof(ElemSN));
printf("Please input node data:");
scanf("%d", &x);
p->data = x;
p->next = h->next;
h->next = p;
h = h->next;
}
h = h->next; //确保h最后指向的是第一个创建的结点,而非最后一个
return h;
}
void print_link(ElemSN *head)
{
ElemSN *p;
if(NULL == head)
{
printf("Link is null.\n");
return;
}
p = head;
do //使用do-while结构输出
{
printf("%d ", p->data);
p = p->next;
}while(p != head);
printf("\n");
}
ElemSN * delete_node(ElemSN *head, int x)
{
ElemSN *p, *q;
int flag = 0;
p = head;
if(p->next == p) //只有一个结点的情况需要单独处理
{
if(p->data == x)
{
free(p);
p = NULL;
return p;
}
}
do
{
if(x == p->next->data) //注意这里用的是p->next->data
{
flag = 1;
break;
}
p = p->next;
}while(p != head);
if(p->next == head) //删除头结点
{
head = head->next;
free(p->next);
p->next = head;
return head;
}
if(flag)
{
q = p->next;
p->next = q->next;
free(q);
}
return head;
}
ElemSN * clear_link(ElemSN *head)
{
ElemSN *p, *q;
p = head;
if(NULL == p)
{
return NULL;
}
do
{
q = p->next;
free(p);
p = q;
}while(p != head);
head = NULL;
return head;
}