栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

将带有头节点长度为N的链表用迭代法和递归法以及最笨的方法进行翻转((A-B-C)-(C-B-A))

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

将带有头节点长度为N的链表用迭代法和递归法以及最笨的方法进行翻转((A-B-C)-(C-B-A))

       本人第一次发表文章,若有不妥之处,望大家指出,我加以改正。 

  一、迭代法:是一种不断用变量的旧值递推出新值的解决问题的一种方法。本题中用于新旧结点的替换。

具体实现反转的思想和算法如下: 

//迭代
linklist Reversal(linklist phead)
{
	Node *p,*q,*s;
	if(N>1)
	{
	    p=phead->next;
     	q=p->next;
	    if(N>=3) s=q->next;//若节点数大于等于3,那么就可以使用s
	    q->next=p;
	    p->next=NULL;
	    phead->next=q;
	    if(N>=3)
		{
			while(s)
			{
				p=q;
				q=s;
				s=s->next;
				q->next=p;
				phead->next=q;
			}
		}
	}
	return phead;
}

 总的来说就是将后一个结点插入到前一个结点,注意要让第一个结点指为空(非头节点)。

具体实现还要创建链表和遍历链表,具体代码如下:

#include
#include
#include
#define N 3  //需要进行创建数据的数目 

typedef struct Date {
	int num;
	struct Date *next;
}*linklist,Node;

linklist Creatlist(void);//创建链表
void Printlist(linklist phead);//遍历链表
linklist Reversal(linklist phead);//进行反转链表


int main() {
	linklist head,lhead;
	printf("nn*******开始创建单链表**********nn");
	head=Creatlist();
	if(!head||!head->next) { //判断有无头节点或是否只有头节点,若是将退出程序 
		printf("数据区为空!!!创建失败!!nn");
		getch();//键入任何字符将继续
		return 0;
	}
	printf("n*******创建成功!************nn");
	Printlist(head);
	printf("*******正在反转单链表**********nn");
	printf("*******反转成功!!!**********nn");
	lhead=Reversal(head);
	Printlist(lhead);
	getch();//程序暂停,按任意键继续(字符不外显)
//	system("pause");//系统暂停 ,按任意键继续。
	return 0;
}

linklist Creatlist() {
	int n,counter;
	linklist phead;
	Node *r,*s;
	counter=0;
	phead=(Node*)malloc(sizeof(Node));
	phead->next=NULL;
	r=phead;
	while(counternum=n;
		s->next=NULL;
		r->next=s;
		r=s;
	}
//	free(s);//若写,创建的最后一个节点的数据将会出现错乱,从而引起程序崩溃!!
	return phead;
}

void Printlist(linklist phead) {
	int flag=1;//控制“->”的打印
	linklist p;
	p=phead->next;
	printf("操作完成的链表:");
	while(p) {
		if(flag!=1) printf("->");
		printf("%d",p->num);
		p=p->next;
		flag++;
	}
	printf("nnn");
}
//迭代
linklist Reversal(linklist phead)
{
	Node *p,*q,*s;
	if(N>1)
	{
	    p=phead->next;
     	q=p->next;
	    if(N>=3) s=q->next;//若节点数大于等于3,那么就可以使用s
	    q->next=p;
	    p->next=NULL;
	    phead->next=q;
	    if(N>=3)
		{
			while(s)
			{
				p=q;
				q=s;
				s=s->next;
				q->next=p;
				phead->next=q;
			}
		}
	}
	return phead;
}

 

二、只要咱们每次找到最后一个结点并将这些节点重新组成一个链表即可,具体代码如下:

#include
#include
#include
#define N 3  //需要进行创建数据的数目 

typedef struct Date {
	int num;
	struct Date *next;
}*linklist,Node;

linklist Creatlist(void);//创建链表
void Printlist(linklist phead);//遍历链表
linklist Reversal(linklist phead);//进行反转链表
linklist Lastnode(linklist phead);//获取链表最后一个结点 


int main() {
	linklist head,lhead;
	printf("nn*******开始创建单链表**********nn");
	head=Creatlist();
	if(!head||!head->next) { //判断有无头节点或是否只有头节点,若是将退出程序 
		printf("数据区为空!!!创建失败!!nn");
		getch();//键入任何字符将继续
		return 0;
	}
	printf("n*******创建成功!************nn");
	Printlist(head);
	printf("*******正在反转单链表**********nn");
	printf("*******反转成功!!!**********nn");
//	lhead=(Node*)malloc(sizeof(Node));//digui
//	lhead->next=NULL;//digui
//	lhead->next=Reversal(head->next);//digui
	lhead=Reversal(head); 
	Printlist(lhead);
	getch();//程序暂停,按任意键继续(字符不外显)
//	system("pause");//系统暂停 ,按任意键继续。
	return 0;
}

linklist Creatlist() {
	int n,counter;
	linklist phead;
	Node *r,*s;
	counter=0;
	phead=(Node*)malloc(sizeof(Node));
	phead->next=NULL;
	r=phead;
	while(counternum=n;
		s->next=NULL;
		r->next=s;
		r=s;
	}
//	free(s);//若写,创建的最后一个节点的数据将会出现错乱,从而引起程序崩溃!!
	return phead;
}

void Printlist(linklist phead) {
	int flag=1;//控制“->”的打印
	linklist p;
	p=phead->next;
	printf("操作完成的链表:");
	while(p) {
		if(flag!=1) printf("->");
		printf("%d",p->num);
		p=p->next;
		flag++;
	}
	printf("nnn");
}
linklist Lastnode(linklist phead) {
	Node *p,*q;
	p=phead;
	q=p->next; 
	while(q->next) {
		p=p->next;//倒数第二个节点 
		q=p->next;//最后一个结点 
	}
	p->next=NULL;//删除最后一个节点 
	return q;
}

linklist Reversal(linklist phead) {
	linklist nhead=NULL;
	Node *q,*s;//q为新链表创建时所用的过渡结点 ,s不断接收旧链表最后一个结点 
	nhead=(Node*)malloc(sizeof(Node));//反转后链表的新头节点 
	nhead->next=NULL;
	q=nhead;
	while(phead->next) //当旧链表只剩一个头节点,所有子节点都被s接收后,循环结束 
	{
		s=Lastnode(phead);
		q->next=s;
		q=s;
	}
	return nhead;
}

三、递归调用法(调用自身函数从后往前获取每个节点组成新链表)

具体实现代码如下

#include
#include
#include
#define N 7  //需要进行创建数据的数目 

typedef struct Date {
	int num;
	struct Date *next;
}*linklist,Node;

linklist Creatlist(void);//创建链表
void Printlist(linklist phead);//遍历链表
linklist Reversal(linklist phead);//进行反转链表


int main() {
	linklist head,lhead;
	printf("nn*******开始创建单链表**********nn");
	head=Creatlist();
	if(!head||!head->next) { //判断有无头节点或是否只有头节点,若是将退出程序 
		printf("数据区为空!!!创建失败!!nn");
		getch();//键入任何字符将继续
		return 0;
	}
	printf("n*******创建成功!************nn");
	Printlist(head);
	printf("*******正在反转单链表**********nn");
	printf("*******反转成功!!!**********nn");
	lhead=(Node*)malloc(sizeof(Node));//digui
	lhead->next=NULL;//digui
	lhead->next=Reversal(head->next);//digui
	Printlist(lhead);
	getch();//程序暂停,按任意键继续(字符不外显)
//	system("pause");//系统暂停 ,按任意键继续。
	return 0;
}

linklist Creatlist() {
	int n,counter;
	linklist phead;
	Node *r,*s;
	counter=0;
	phead=(Node*)malloc(sizeof(Node));
	phead->next=NULL;
	r=phead;
	while(counternum=n;
		s->next=NULL;
		r->next=s;
		r=s;
	}
//	free(s);//若写,创建的最后一个节点的数据将会出现错乱,从而引起程序崩溃!!
	return phead;
}

void Printlist(linklist phead) {
	int flag=1;//控制“->”的打印
	linklist p;
	p=phead->next;
	printf("操作完成的链表:");
	while(p) {
		if(flag!=1) printf("->");
		printf("%d",p->num);
		p=p->next;
		flag++;
	}
	printf("nnn");
}

linklist Reversal(linklist phead)//递归法 
{
	linklist newhead=NULL; //创建第一个结点并接收原链表最后一个结点。 
	if(!phead->next) return phead;//返回最后一个结点 。 
	newhead=Reversal(phead->next);//调用自身找到最后一个结点(结点:phead->next)。 
	phead->next->next=phead;// 最后一个结点(phead->next)指向倒数第二个节点个结点(phead)。 
	phead->next=NULL;//断开原先的最后一个结点和倒数第二个节点,即使倒数第二个节点指为NULL 。 
	return newhead;//返回新链表的第一个结点。	
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/529659.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号