双链表操作

/*  
    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);


}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值