数据结构_双向循环链表

#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){//在非递减有序双向循环链表中实现插入元素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的结点  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);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值