/*
1.利用尾插法建立一个双向循环链表。
2.遍历双向循环链表。
3.实现双向循环链表中删除一个指定元素。
4.在非递减有序双向循环链表中实现插入元素e仍有序算法。
5.判断双向循环链表中元素是否对称若对称返回1否则返回0。
6.设元素为正整型,实现算法把所有奇数排列在偶数之前。
7.在主函数中设计一个简单的菜单调试上述算法。
*/
#include <stdio.h> #include <stdlib.h> typedef int elemtype; typedef struct lnode //定义结点类型 { elemtype data; struct lnode *next; struct lnode *prior; }lnode,*linklist; int initlist(linklist &L) //初始化单链表 { L=(linklist)malloc(sizeof(lnode)); //表头附加结点 if(!L) exit(-2); L->next=L; L->prior=L; return 1; }//初始化了一个空表 void createlist(linklist &L) //尾插法生成双向循环链表 { int x; linklist q=L; printf("请输入要插入元素的值(输入0结束):\n"); scanf("%d",&x); while(x){ linklist p=(linklist)malloc(sizeof(lnode)); p->data=x; q->next=p; L->prior=p; p->prior=q; p->next=L; q=p; scanf("%d",&x); } } void shuchulist(linklist &L) //遍历有头结点的双向循环链表 { linklist p=L->next; while(p->next!=L){ printf("%4d",p->data); p=p->next; } printf("%4d",p->data); printf("\n"); } int lengthlist(linklist L){//统计链表长度 linklist p=L->next; int count=0; while(p!=L){ p=p->next; count++; } return count; } int listdelete_i(linklist &L,int i){//删除带头结点的双向循环链表第i个元素 linklist p=L; int j=0; if(i>lengthlist(L)){ return 0; } while(j<i){//寻找第i个结点,并令p指向此结点 p=p->next; ++j; } p->prior->next=p->next;//删除结点p free(p);//释放结点p return 1; } int listdelete_x(linklist &L,elemtype x){//删除值 为x的元素 linklist p=L->next,q; int i=0; while(p!=L){ if(p->data==x){ q=p->next; p->next->prior=p->prior; p->prior->next=p->next; free(p); p=q; ++i; } else p=p->next; } return i; } void paixu(linklist L){//将链表排成非递减链表 int t; linklist p; for(int i=1;i<lengthlist(L);i++){ p=L->next; for(int j=0;j<lengthlist(L)-i;j++){ if(p->data>p->next->data){ t=p->data; p->data=p->next->data; p->next->data=t; } p=p->next; } } } void linklistinsert(linklist &L,elemtype e){// linklist p=L->next; linklist q=(linklist)malloc(sizeof(lnode)); q->data=e; if(L->prior->data<e){//把元素e插到最后 L->prior->next=q; q->prior=L->prior; q->next=L; L->prior=q; }else{ while(p->data<e){//找到第一个大于或等于e 的元素 p=p->next; } //把e插到第一个大于或等于它的元素之前 p->prior->next=q; q->prior=p->prior; q->next=p; p->prior=q; } } int panduan(linklist L){//判断双向循环链表元素是否对称 linklist p=L->next,q=L->prior; if(lengthlist(L)%2){ while(p->data==q->data&&p!=q){ p=p->next;q=q->prior; } if(q==p) return 1; else return 0; }else{ while(p->data==q->data&&p->next!=q){ p=p->next;q=q->prior; } if(p->data==q->data) return 1; else return 0; } } void jioushu(linklist L){//把链表中奇数放到偶数之前 linklist p=L->next,q,s; s=L->prior; while(p!=s){ if(p->data%2) p=p->next; else{ q=p->next; p->prior->next=p->next; p->next ->prior=p->prior;//把p从链表中取出 p->prior=L->prior; L->prior->next=p; p->next=L; L->prior=p; p=q; } } } void main() { linklist La; int menu,flag,i,x,c; do{ printf("1.利用尾插法建立双向循环链表\n"); printf("2.遍历双向循环链表\n"); printf("3.双向循环链表中删除一个指定元素\n"); printf("4.在非递减有序双向循环链表中实现插入元素e仍有序\n"); printf("5.判断双向循环链表中元素是否对称若对称返回1否则返回0\n"); printf("6.设元素为正整型,实现算法把所有奇数排列在偶数之前\n"); printf("0.退出\n"); printf("\n:请输入所选 菜单(0~6) "); scanf("%d",&menu); switch(menu){ case 1: initlist(La);createlist(La);break; case 2: printf("链表中的元素为:\n");shuchulist(La);break; case 3: printf("请先把删除方式:1 删除值为x的结点\n 2 删除第i个结点 "); scanf("%d",&c); if(c==1){ printf("请输入要删除元素的值: "); scanf("%d",&x); flag=listdelete_x(La,x); if(flag){ printf("删除成功!\n"); printf("删除之后的链表为:\n"); shuchulist(La); }else printf("删除失败!\n"); }else if(c==2){ printf("请输入要删除的位置: "); scanf("%d",&i); flag=listdelete_i(La,i); if(flag){ printf("删除成功!\n"); printf("删除之后的链表为:\n"); shuchulist(La); }else printf("删除失败!\n"); } break; case 4: printf("把原始链表初始化为非递减有序链表为:\n"); paixu(La); shuchulist(La); printf("请输入要插入的元素的值: "); scanf("%d",&x); linklistinsert(La,x); printf("插入后的链表为:\n"); shuchulist(La); break; case 5: flag=panduan(La); if(flag) printf("链表对称!\n"); else printf("链表不对称!\n"); break; case 6: printf("排列之前为:\n"); shuchulist(La); jioushu(La); printf("排列之后为\n"); shuchulist(La); break; case 0: exit(0); } }while(menu); }