/*
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);
}
本文介绍了一种使用尾插法创建双向循环链表的方法,并提供了遍历、删除、排序及特殊操作等实用功能的实现。此外,还展示了如何通过一个简易菜单来调试这些功能。

170

被折叠的 条评论
为什么被折叠?



