苦逼的双向循环链表
以前不怎么写链表,更不怎么用C++写链表,导致这次写双向循环的时候直接萎了。
其实思想很简单,就是细节比较多……
别的不说了,直接上代码。(第一,这个不是我写的,第二,这个是C)
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);
仅仅留个资料而已。