双向循环链表
#include<stdio.h> #include<stdlib.h> #include<malloc.h> #include<assert.h> //双向循环链表的结构体定义 typedef struct node { int data; struct node *prior; struct node *next; }NODE,*PNODE,*LINKLIST; //初始化 void init(LINKLIST *list) { *list = (PNODE)malloc(sizeof(NODE)); (*list)->next = *list; (*list)->prior = *list; } //添加 void add(LINKLIST list,int data) { PNODE p=list,q; q=(PNODE)malloc(sizeof(NODE));//q为要插入的节点 q->data =data; q->next = p; q->prior = p->prior; if(p->prior) p->prior->next = q; p->prior = q; } //插入 i>=1 void insert(LINKLIST list,int i,int data) { PNODE p=list,q; //将p移动到i-1个位置 while(--i && p->next!=list) { p=p->next; } assert(i==0); q = (PNODE)malloc(sizeof(NODE));//q为需要插入的节点 q->data =data; q->next = p->next; q->prior = p; if(p->next) p->next->prior = q; p->next = q; } //删除 void del(LINKLIST list,int i,int *data) { PNODE p=list,q; //将p移动到第i-1个位置 while(--i && p->next!=list) { p=p->next; } assert(i==0 && p->next!=list); q = p->next;//q为要删除的节点 *data = q->data;//将删除的节点的数据域返回 p->next = q->next;//p断开与q连接,和q的后继相连 if(q->next) q->next->prior = p;//如果删除节点存在后继,那么将这个的prior的指向p }//end del //获取双向循环链表的长度 int getLen(LINKLIST list) { PNODE p=list; int i=0; while((p=p->next)!=list) { i++; } return i; } //获取第i个位置的数据 int getData(LINKLIST list,int i) { PNODE p=list; //将p移动到第i个位置 while(i--) { p=p->next; assert(p!=list); } return p->data; } //正转一圈输出 void display1(LINKLIST list) { PNODE p=list; while((p=p->next)!=list) { printf("%d ",p->data); }//end while printf("\n"); } //正转两圈输出 void display2(LINKLIST list) { int count=0;//统计p转到list个数 PNODE p=list; while(count<2) { p=p->next; if(p==list) { count++; continue; }else { printf("%d ",p->data); } } printf("\n"); } //反转一圈输出 void display_1(LINKLIST list) { PNODE p=list; while((p=p->prior)!=list) { printf("%d ",p->data); } printf("\n"); } //反转两圈输出 void display_2(LINKLIST list) { int count=0;//统计p转到list个数 PNODE p=list; while(count<2) { p=p->prior; if(p==list) { count++; continue; }else { printf("%d ",p->data); } } printf("\n"); } //销毁 void destroy(LINKLIST *list) { PNODE p = *list,q; while(p->next != *list) { q=p->next; free(p); p = q; } *list = NULL; } //显示菜单 void displaymenu() { printf("**********这是一个双向循环链表的基本操作程序**********\n"); printf("\t\t\t1,添加\n"); printf("\t\t\t2,插入\n"); printf("\t\t\t3,删除\n"); printf("\t\t\t4,获取长度\n"); printf("\t\t\t5,获取数据\n"); printf("\t\t\t6,正转输出一圈\n"); printf("\t\t\t7,正转输出两圈\n"); printf("\t\t\t8,反转输出一圈\n"); printf("\t\t\t9,反转输出两圈\n"); printf("\t\t\t0,销毁退出\n"); }//end displaymenu int main() { int i,j,choice,flag=1; LINKLIST list=NULL; init(&list);//初始化链表 displaymenu();//显示菜单 while(flag) { printf("请选择你要的操作:"); scanf("%d",&choice);//输入 switch (choice) { case 1: printf("--你当前选择了添加操作-- (说明:按组合键ctrl+Z并回车可结束添加操作)\n"); while(scanf("%d",&i)!=EOF) { add(list,i); }//end while printf("--添加操作结束--\n\n"); break; case 2: printf("--你当前选择了插入操作--\n"); printf("--请输入插入元素的数据:"); scanf("%d",&j); printf("--请输入插入位置:"); scanf("%d",&i); insert(list,i,j); printf("--插入结束--\n\n"); break; case 3: printf("--你当前选择了删除操作--\n"); printf("--请输入删除位置:"); scanf("%d",&i); del(list,i,&j); printf("--你删除的元素的数据:%d \n",j); printf("--删除结束--\n\n"); break; case 4: printf("--你当前选择了获取长度操作--\n"); printf("双向循环链表的长度:%d\n",getLen(list)); printf("--获取表长结束--\n\n"); break; case 5: printf("--你当前选择了获取数据操作--\n"); printf("--请输入你要获取元素的位置:"); scanf("%d",&i); printf("第%d个位置的数据为:%d\n",i,getData(list,i)); printf("--获取数据结束--\n"); break; case 6: printf("--你当前选择了正转输出一圈操作--\n"); display1(list); printf("--正转输出一圈操作结束--\n\n"); break; case 7: printf("--你当前选择了正转输出两圈操作--\n"); display2(list); printf("--正转输出两圈操作结束--\n\n"); break; case 8: printf("--你当前选择了反转输出一圈操作--\n"); display_1(list); printf("--反转输出一圈操作结束--\n\n"); break; case 9: printf("--你当前选择了反转输出两圈操作--\n"); display_2(list); printf("--反转输出两圈操作结束--\n\n"); break; case 0: printf("--你当前选择了销毁并退出操作--\n"); destroy(&list);//销毁链表 flag=0;//退出循环 printf("--退出操作结束--\n\n"); break; default: printf("--你选择错误!\n\n"); break; }//end switch }//end while(flag) system("pause"); return 0; }