双向链表&循环链表

本文介绍了链表的基础知识,包括双向链表和循环链表的实现,提供了按元素删除、按位置插入等操作。此外,还涉及到了约瑟夫环问题的解决以及单向链表的选择排序算法实现。
摘要由CSDN通过智能技术生成

        今天对链表有了更深入的了解,昨天学的链表是单向的,你会发现一个问题就是如果链表进行p = p->next;后p会找不到之前的结点。这就会引入双向链表的概念,它拥有2个指针域,一个数据域,头结点定义的时候,指针域指的是链表长度,设置为0,假定2个指针域一个为prev一个为next,那么头结点的指针域初始化如下p->next = NULL; p->prev = NULL;然后就是循环链表了,循环单链表,循环双链表,它们唯一和之前的不同在于,头结点的prev指针指向尾结点,尾结点的next指针指向头结点。还需要注意的是循环链表在插入删除的时候比普通链表更加麻烦,但也跟我们带来了许多便利。 下面是今天的xmid

 练习:

 main.c

1.双向链表按元素删除

LinklistDouble *p = LinklistDoubleSpace();	
	p->len = 0;
	p->prev == NULL;
	p->next == NULL;
	while(1){
		printf("==========双向链表=========\n");
		printf("1插入\t2输出\n3查找\t4删除\n5退出\n");
		int choice;
		printf("请输入操作: \n");
		scanf("%d",&choice);
		getchar();
		if(choice == 1){
			LinklistDoubleInsert(p);
			p->len ++;
		}
		else if(choice == 2){
			LinklistDoublePrint(p);
		}
		else if(choice == 3){
			LinklistDouble *q = LinklistDoubleSearch(p);
			if(q == NULL){
				printf("查找失败\n");
			}
			else{
				printf("查找成功,该元素的地址是: %p\n",q);
			}
		}
		else if(choice == 4){
			LinklistDoubleDelete(p);
		}
		else if(choice == 5){
			break;
		}
	}
	free(p);
	p == NULL;

2.循环双向链表按位置插入

printf("==========双向循环链表=========\n");
	LinklistDoubleLoop *k = LinklistDoubleLoopSpace();
	k->len = 0;
	k->next = k;
	k->prev = k;
	while(1){
		printf("1插入\t2输出\n3退出\n");
		int choice;
		printf("请输入操作: \n");
		scanf("%d",&choice);
		getchar();
		if(choice == 1){
			LinklistDoubleLoopInsert(k);
		}
		else if(choice == 2){
			LinklistDoubleLoopPrint(k);
		}
		else if(choice == 3){
			break;
		}		
	}
	free(k);
	k == NULL;

3.实现约瑟夫环

4.删除链表中的所有结点

5.实现单向链表的简单选择排序

printf("==========单向循环链表=========\n");
	SinglyLinklist *w = SinglyLinklistSpace();	
	w->len = 0;
	w->next = w;
	while(1){
		printf("1插入\t2输出\n3约瑟夫\t4排序\n5逆置\t6退出\n");
		int choice;
		printf("请输入操作: ");
		scanf("%d",&choice);
		getchar();
		if(choice == 1){
			SinglyLinklistInsert(w);
		}
		else if(choice == 2){
			SinglyLinklistPrint(w);
		}
		else if(choice == 3){
			SinglyLinklistJoseph(w);
			w->next = w;
		}
		else if(choice == 4){
			SinglyLinklistSorting(w);
		}	
		else if(choice == 5){
			SinglyLinklistNiZhi(w);
		}
		else if(choice == 6){
			break;
		}
	}

head.h

1.双向链表按元素删除

typedef struct node {
	union{
		int len;
		char data;
	};
	struct node *prev;
	struct node *next;
}LinklistDouble;


LinklistDouble *LinklistDoubleSpace();

void LinklistDoubleInsert(LinklistDouble *p);

void LinklistDoublePrint(LinklistDouble *p);

LinklistDouble *LinklistDoubleSearch(LinklistDouble *p);

void LinklistDoubleDelete(LinklistDouble *p);

2.循环双向链表按位置插入

typedef struct node2 {
	union{
		int len;
		char data;
	};
	struct node2 *prev;
	struct node2 *next;
}LinklistDoubleLoop;


LinklistDoubleLoop *LinklistDoubleLoopSpace();

LinklistDoubleLoop *LinklistDoubleLoopSearch(LinklistDoubleLoop *p);

void LinklistDoubleLoopInsert(LinklistDoubleLoop *p);

void LinklistDoubleLoopPrint(LinklistDoubleLoop *p);

3.实现约瑟夫环

4.删除链表中的所有结点

5.实现单向链表的简单选择排序

typedef struct node3{
	union{
		int len;
		char data;
	};
	struct node3 *next;
}SinglyLinklist;

SinglyLinklist *SinglyLinklistSpace();

void SinglyLinklistInsert(SinglyLinklist *p);

void SinglyLinklistPrint(SinglyLinklist *p);

void SinglyLinklistJoseph(SinglyLinklist *p);

void SinglyLinklistSorting(SinglyLinklist *p);

void SinglyLinklistNiZhi(SinglyLinklist *p);

fun.c

1.双向链表按元素删除

LinklistDouble *LinklistDoubleSpace(){
	LinklistDouble *p = (LinklistDouble *)malloc(sizeof(LinklistDouble));
	if(p == NULL){
		return NULL;
	}
	return p;
}

void LinklistDoubleInsert(LinklistDouble *p){
	LinklistDouble *k = LinklistDoubleSpace();
	printf("请输入新的数据: ");
	scanf("%c",&k->data);
	getchar();
	k->next = p->next;
	k->prev = p;
	if(k->next){
		k->next->prev = k;
	}
	p->next = k;
	printf("插入成功!\n");
}

void LinklistDoublePrint(LinklistDouble *p){
	while(p->next){
		p = p->next;
		printf("%c ",p->data);
	}
	printf("\n");
	while(p->prev){
		printf("%c ",p->data);
		p = p->prev;
	}
	printf("\n");
}

LinklistDouble *LinklistDoubleSearch(LinklistDouble *p){
	if(!(p->next)){
		printf("该链表空了,不能操作。\n");
		return NULL;
	}
	printf("请输入你要查找的元素: ");
	char search;
	scanf("%c",&search);
	getchar();
	while(p->next != NULL && p->next->data != search){
		p = p->next;
	}
	return p->next;
}

void LinklistDoubleDelete(LinklistDouble *p){
	LinklistDouble *q = LinklistDoubleSearch(p);
	if(q == NULL){
		printf("删除失败!\n");
		return;
	}
	q->prev->next = q->next;
	if(q->next)
		q->next->prev = q->prev;
	p->len --;
	printf("删除成功!\n");
}

2.循环双向链表按位置插入

LinklistDoubleLoop *LinklistDoubleLoopSpace(){
	LinklistDoubleLoop *p = (LinklistDoubleLoop *)malloc(sizeof(LinklistDoubleLoop));
	if(p == NULL){
		return NULL;
	}
	return p;
}

LinklistDoubleLoop *LinklistDoubleLoopSearch(LinklistDoubleLoop *p){
	printf("请输入插入的位置: ");
	int mid;
	scanf("%d",&mid);
	getchar();
	if(mid < 1 || mid > p->len + 1){
		return NULL;
	}
	while(mid > 1){
		p = p->next;
		mid --;
	}
	return p;
}

void LinklistDoubleLoopInsert(LinklistDoubleLoop *p){
	LinklistDoubleLoop *q = LinklistDoubleLoopSearch(p);
	if(q == NULL){
		printf("插入位置不合法!\n");
		return;
	}
	LinklistDoubleLoop *k = LinklistDoubleLoopSpace();
	printf("请输入插入的值: ");
	scanf("%c",&k->data);
	getchar();
	k->next = q->next;
	k->prev = q;
	q->next->prev = k;
	q->next = k;
	p->len ++;
	printf("插入成功\n");
}

void LinklistDoubleLoopPrint(LinklistDoubleLoop *p){
	LinklistDoubleLoop *q = p;
	printf("链表如下: \n");
	while(p->next != q){
		p = p->next;
		printf("%c ",p->data);
	}
	printf("\n");
	while(p->prev != q){
		printf("%c ",p->data);
		p = p->prev;	
	}
	printf("\n");
}

3.实现约瑟夫环

4.删除链表中的所有结点

5.实现单向链表的简单选择排序

SinglyLinklist *SinglyLinklistSpace(){
	SinglyLinklist *p = (SinglyLinklist *)malloc(sizeof(SinglyLinklist));
	if(p == NULL){
		return NULL;
	}
	return p;
}

void SinglyLinklistInsert(SinglyLinklist *p){
	SinglyLinklist *k = SinglyLinklistSpace();
	printf("请输入插入的值: ");
	scanf("%c",&k->data);
	getchar();
	p->len ++;
	SinglyLinklist *q = p;
	while(p->next != q && p->next->data < k->data){
		p = p->next;
	}
	printf("%c\n",p->data);
	k->next = p->next;
	p->next = k;
	printf("插入成功\n");
}

void SinglyLinklistPrint(SinglyLinklist *p){
	SinglyLinklist *q = p;
	while(p->next != q){
		p = p->next;
		printf("%c ",p->data);
	}
	printf("\n");
}

void SinglyLinklistJoseph(SinglyLinklist *p){
	SinglyLinklist *q = p;
	printf("请输入数到第几个移出链表: \n");
	int n;
	scanf("%d",&n);
	getchar();
	while(q->len){
		for(int i = 0; i < n-1; i ++){
			p = p->next;
			if(p == q){
				i --;
			}
		}
		SinglyLinklist *k = p->next;
		if(k == q){
			k = q->next;
		}
		printf("%c ",k->data);
		p->next = k->next;
		free(k);
		k == NULL;
		q->len --;
	}
	printf("\n");
}

void SinglyLinklistSorting(SinglyLinklist *p){
	SinglyLinklist *q = p->next;
	for(;q != p; q = q->next){
		SinglyLinklist *max = q;
		for(SinglyLinklist *w = q->next; w != p; w = w->next){
			if(max->data < w->data){
				max = w;
			}
		}
		if(max != q){
			int mid = max->data;
			max->data = q->data;
			q->data = mid;
		}
	}
} 

void SinglyLinklistNiZhi(SinglyLinklist *p){
	SinglyLinklist *q = p->next;
	p->next = p;
	while(q != p){
		SinglyLinklist *k = q;
		q = q->next;
		k->next = p->next;
		p->next = k;

	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值