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

我的链表笔记2,阳光快乐的每一天都要扣代码哦

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

我的链表笔记2,阳光快乐的每一天都要扣代码哦

题目:设有一个带头结点的循环单链表, 其结点值均为正整数。设计一个算法, 反复找出单链表中结点值最小的结点并输出,然后将该结点从中删除,直到单链表空为止,再删除表头结点。

思路:每次找出最小节点,删除并继续操作,直到整个链表为空,注意判断条件的变化

//19 循环单链表的最小值
void cycleListMinNode(LinkList &L){
	//L的next不为空继续循环 
	while(L->next!=L){
		//初始化四个节点,minnode保存最小值的节点,p保存当前节点,pre保存最小值的前驱,q保存前驱节点 
		LinkList pre=L,p=L->next,minpre=pre,minnode=p;
	//循环遍历 
	while(p!=L){
		//如果x比当前节点的值大,更新minnode 
		if(p->data < minnode->data){
			//最小节点更新 
			minnode = p;
			//最小前驱更新 
			minpre = pre;
		}
		//前驱更新 
		pre = p;
		//继续遍历 
		p=p->next;
	}
	//删除操作 
	minpre->next = minnode->next;
	//打印最小值节点 
	printf("%d,",minnode->data);
	//释放最小值节点 
	free(minnode); 
	}
	//释放链头 
	free(L);
} 
题目:  单链表有环,是指单链表的最后一个结点的指针指向了链表中的某个结点( 通常单链表的最后一个结点的指针域是空的). 试编写算法判断单链表是否存在环。

思路:快慢指针,新建两个指针p,q,q比p始终快一个指针,若pq相遇则代表有环存在

//21环问题
bool islisthaveloop(LinkList &L){
	//初始化节点 
	LinkList slow = L->next,fast = slow;
	//链表遍历 
	while(fast){
		//如果快慢指针相遇,则返回真 
		if(slow==fast){
			return true;
		}
		//继续遍历后移 
		slow = slow->next;
		//快指针每回移动2个位置 
		fast = fast->next->next;
	}
	//循环打破,链表没环,返回假 
	return false;
} 
题目:〖2009 统考真题〗已知一个带有表头结点的单链表, 结点结构为data,next。 假设该链表只给出了头指针list. 在不改变链表的前提下, 请设计一个尽可能高效的算法, 查找链表中倒数第k个位置上的结点(k为正整数). 若查找成功,算法输出该结点的data 域的值,并返回1,否则,只返回0 。

思路: 新建两个指针p,q,p先向后移k个单位,然后pq一起移动,直到p为空,这个时候q指向的结点就为k了。

//22,09年真题
int findk(LinkList L,int k){
	//设置次数计算 
	int count = 0;
	//初始化节点 
	LinkList p = L->next,q = p;
	//遍历链表 
	while(p){
		//如果count小于k,也就是没达到k的位置,让p继续后移 
		if(countnext;
			//计数加加 
			count++;
		}else{
			//p后移 
			p = p->next;
			//q后移 
			q = q->next;
		}
	}
	//如果count怎样都小于k,则数组长度不够,直接返回0 
	if(countdata);
		return 1;
	}
} 
 题目:〖2012 统考真题〗假定采用带头结点的单链表保存单词 当两个单词有相同的后缀时,可共享相同的后缀存储空间,例如  “loading”和 “ being ”的存储映像如下图所示:
设strl 和str2 分别指向两个单词所在单链表的头结点,链表结点结构为{data,*next}请设计一个时间上尽可能高效的算法, 找出由strl 和str2 所指向两个链表共同后缀的起始位置( 如图中字符所在结点的位置p )

思路:计算两个链表长度,比较大小选出较长的链表,循环找到与短链表首个位置相同的节点,然后再一个个对比直到找到相同的节点即可!

//12年真题
LinkList sharewordspace(LinkList &str1,LinkList &str2){
    //初始化两个链表的长度 
	int ls1=0,ls2=0;
	//取别名,防止后续头节点被覆盖 
	LinkList s1 = str1,s2=str2;
	//计算s1的长度 
	while(s1){
		ls1++;
		s1 = s1->next;
	}
	//计算s2的长度 
	while(s2){
		ls2++;
		s2 = s2->next;
	}
	//初始化长链表和短链表 
	LinkList shortList,longList;
	//保存长度 
	int shortl,longl;
	//对比哪个链表更长并装入对应节点中 
	if(s2>s1){
		shortList = s1;
		longList = s2;
		longl = ls2;
		shortl = ls1;
	}else{
		shortList = s2;
		longList = s1;
		longl = ls1;
		shortl = ls2;
	}
	//计算距离 
	int distance = longl - shortl;
	//长链表移动到短链表起始位置 
	while(longList && distance >0){
		longList = longList->next;
		distance--;
	}
	//寻找共用节点 
	while(longList && shortList){
		if(longList == shortList)return longList;
		longList = longList->next;
		shortList = shortList->next;
	}
	//找不到返回空 
	return NULL;
} 

题目:

【15年统考真题】 用单链表保存m个整数, 结点的结构为[data] [link], 且|data|<=n (n为正整数).现要求设计一个时间复杂度尽可能高效的算法, 对于链表中data 的绝对值相等的结点, 仅保留第一次出现的结点而删除其余绝对值相等的结点

思路: 新建一个辅助数组,长度为n+1。若节点的绝对值出现过则值对应下标数组为1,若一为1则对节点删除。

//15年真题
void deletesamenode(LinkList &L,int n){
	//数组开辟 
	int *a = (int*)malloc(sizeof(int)*(n+1));
	//赋值数组,使下标为空 
	for(int i=0;inext,pre=L,r; 
	//中间变量x 
	int x;
	//遍历链表p 
	while(p){
		//获取节点值,赋值于x内 
		x = p->data;
		//取x的绝对值 
		if(x<0)x=-x;
		//判断数组内的x是否出现过 
		if(a[x]!=1){
			//未出现过赋值1 
			a[x]=1;
			//记录前驱 
			pre = p;
			//继续后移 
		    p = p->next;
		}else{
			//删除操作,保存节点 
			r = p;
			//前驱后移 
			pre->next = p->next;
			//节点后移 
			p = p->next;
			//释放节点 
			free(r);
		}
	}
} 
 题目: [ 2019 统考真题] 设线性表L=(a1,a2,a3...,an-2,an-1,an) 采用带头结点的单链表保存,表中的结点定义如下:
typedef struct node
{  int data;
   Struct node*next;
} NODE;
请设计一个空间复杂度为o(1) 且时间上尽可能高效的算法, 重新排列L中的各结点,得到线性表:(a1,an,a2,an-1,a3,an-2....)

要求:
1 ) 给出算法的基本设计思想·
2 ) 根据设计思想, 采用C 或C + + 语言描述算法, 关键之处给出注释·
3 〕说明你所设计的算法的时间复杂度·

思路:先计算长度,取中间节点位置,将链表分为a,b两段,对b链表逆转然后再插入a中,接到L上。

//19年真题 
void  resortLinkList(LinkList &L){
	if(L->next == NULL)return;
	//长度初始化 
	int length = 0,count = 0;
	//初始化节点 
	LinkList p = L->next,a,b,temp,pre,r;
	//计算长度 
	while(p){
		length++;
		p = p->next;
	}
	//取中间值节点的地址 
	p = L->next;
	while(count < length/2){
		count ++;
		p = p->next;
	}
	//将中间节点放入p 
	b = p;
	//前驱设为b 
	pre = b;
	//b后移 
	b = b->next;
	//置首个节点为空 
	pre->next = NULL;
	//b逆转
	while(b){
		temp = b->next;
		b->next = pre;
		pre = b;
		b = temp;
	}
	//得到被反转的首个节点 
	b = pre; 
	//a指向前有序的节点 
	a = L->next;
	//先将L置为空 
	L->next = NULL;
	//r作为前驱指向L 
	r = L;
   //遍历开始
	while(a && b && length>0){
        //奇偶判断
		if(length %2 != 0){
			//p保存后继防止断链 
			p = b->next;
			//后插法,置当前节点的next为空 
			b->next = NULL;
			//前驱指向当前节点 
			r->next = b;
			//前驱更新 
			r = b;
			//b链后移 
			b = p;
		}else{
			//p保存后继防止断链 
			p = a->next;
			//后插法,置当前节点的next为空 
			a->next = NULL;
			//前驱指向当前节点 
			r->next = a;
			//前驱更新 
			r = a;
			//a链后移 
			a = p;
		}
		//长度更新 
		length--;
	} 
} 

以上代码仅供参考,如有错误还请指正,谢谢!

 

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

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

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