【趣学C语言和数据结构100例】

#1024程序员节|征文#

【趣学C语言和数据结构100例】

问题描述

56.设将 n(n>1)个整数存放到区带头结点处单链表乚中,设计算法将L中保存的序列循环石移 k(0<k<n)个位置。例如,若k=1,则将链表(0,1,2,3}变为{3,0,1,2}

57.设有一个带头结点的非循环双链表L,其每个结点中除有 pre、data 和 next 域外,还有一个访问频度域 freq,其值均初始化为零。每当在链表中进行一次 Locate(L,x)运算时,令值为x的结点中 freg 域的值增1,并使此链表中的结点保持按访问频度递减的顺序排列,且最近访问的结点排在频度相同的结点之前,以便使频繁访问的结点总是靠近表头。试编写符合上述要求的 Locate(L,x)函数,返回找到结点的地址,类型为指针型。

58.单链表有环,是指单链表的最后一个结点的指针指向了链表中的某个结点(通常单链表的最后一个结点的指针域是空的)。试编写算法判断单链表是否存在环。

59.设有一个长度 n(n 为偶数)的不带头结点的单链表,且结点值都大于 0,设计算法求这个单链表的最大孪生和。孪生和定义为一个结点值与其孪生结点值之和,对于第i个结点(从开始),其孪生结点为第 n-i个结点。

60.已知一个带有表头结点的单链表,结点结构为 data,next 假设该链表只给出了头指针 L在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k 为正整数)。若查找成功,算法输出该结点的 data 域的值,并返回 1:否则,只返回 0.

代码分析

56.将链表向有移动k个位置 例如:将链表(0,1,2,3}变为{3,0,1,2}

c 复制代码
//链表为空:
if(L==NULL || L->next==NULL){
	return ;
}

思路:首先遍历链表以计算节点数量 n,然后将链表的最后一个节点指向头节点,形成一个循环。接着,通过移动指针找到新的头节点,并断开循环。时间复杂度为O(n),空间复杂度为O(1)

具体分析:链表变化,故函数名为void 函数名(LiukList &L,int k)。如果链表为空,直接返回;所以while循环遍历,同时计数n为长度。在最后使p的下一个指向L,即构成循环链表。使用for循环,p一直向后移动n-k个位置,然后令p的下一个指向空,即断链,最后返回。

57.在双链表中根据访问频度排序

思路:用于查找值为 x 的节点,并更新其访问频度。若找到节点,则将其移动到合适的位置以保持频度递减的顺序。时间复杂度为O(n),空间复杂度为O(1)

具体分析: Locate(L,x)函数,返回找到结点的地址,类型为指针型,故函数名为Lnode * Locate(LiukList L,int x),使用while循环在p不为空且p的data!=x时,一直找到值为x的p。如果p为空,即x不存在,则数据返回p,否则进行下面的操作,先令增加访问频度++,因为是递减,所以如果p是头结点的下一个或p的前一个节点的频度大于p的频度,即(p->pre = = L || p->pre->freq > p->freq),则直接返回p即可。否则,令q记录p的前一个,如果p不是最后一个节点,令p的下一个的前一个指向q,令q指向的下一个指向p的下一个。如果p是最后一个节点,则直接令q指向的下一个指向p的下一个。(为了跳过目前的p)使用while遍历,不到==L时且频度域的值大的位置,向前移动,即找到插入位置。然后使用尾插法,插入p到q之后。先令p的下一个指向q的下一个,先和后面的连接。令p的下一个的前一个指向q。即和后边的正式建立连接。然后令p的前一个指向q,令q的下一个指向p,成功插入。最后返回结点的地址p。

58.单链表是否存在环

思路:使用快慢指针法判断链表是否存在环。如果快指针和慢指针相遇,则说明存在环。

具体分析:定义两个指针都指向L的部。这样他们的下一个不为0。则进行操作,令慢指针每次移动一步,令快指针每次移动一步,如果他们相等,则返回1。如果出了循环,则返回0。(不循环一定会跳出循环)。

59.单链表的最大孪生和

思路:该算法首先找到链表的中点(快慢指针),然后反转后半部分链表( 头插法),最后计算每对孪生节点的和并找出最大值。时间复杂度为O(n),空间复杂度为O(1) 反转用头插 孪生和定义为一个结点值与其孪生结点值之和,对于第i个结点(从开始),其孪生结点为第 n-i个结点。

具体分析:

1.使用快慢指针先找到链表的中点,使用while循环,条件为当快指针指向NULL结束循环,慢指针每次移动一步,令快指针每次移动一步。此时的慢指针为中点。

2.定义一个头部节点,从慢指针开始,令后面的节点使用头插法到新定义的头部节点。头插法的内容:使用s记录slow的下一个,否则断链。令s指向新的头部。将头部更新为slow,使slow变为r,继续工作。

3.计算每对孪生节点,定义p从L出发,定义q从新的头部(为新链表的头部),max=0,使遍历,如果孪生节点的和更大,则记录,一直进行移动.到结束返回max。

60.查找链表倒数第k个位置上的结点(

思路:该算法使用两个指针,p 和 q,在遍历链表时保持 p 比 q 领先 k 个节点。最终,当 p 到达链表末尾时,q 就是倒数第k个节点。时间复杂度为O(n),空间复杂度为O(1)

具体分析:返回值为int,链表不会改变,故函数名为int 函数名(LiukList L,int k);定义p和q两个指针,定义一个计数,使用while循环遍历,在计数<k时,只进行计数++和,p的移动,在不到最后一个的情况下,进行的两个p和q同时移动。结束循环时,q所指的为倒数第k个。如果结束循环时,计数<k,则长度不够,返回0;否则输出结点的值,并返回1。

代码实现

c 复制代码
#include<stdio.h>
int main(){

//	56.设将 n(n>1)个整数存放到区带头结点处单链表乚中,设计算法将L中保存的序列循环石移 k(0<k<n)个位置。例如,若k=1,则将链表(0,1,2,3}变为{3,0,1,2}
//	首先遍历链表以计算节点数量 n,然后将链表的最后一个节点指向头节点,形成一个循环。接着,通过移动指针找到新的头节点,并断开循环。时间复杂度为O(n),空间复杂度为O(1)
void fun(Liuklist &L,int k){
	int n=1;
	LNode *p=L; 
	if(L==NULL || L->next==NULL){
		return ;
	}
	while(p->next != NULL){
		n++;
		p=p>next;
	}
	p->next=L;
	for(int i=1;i<=n-k;i++){
		p=p->next;
	}
	L=p->next;
	p->next=NULL;
	return ;
} 

//	57.设有一个带头结点的非循环双链表L,其每个结点中除有 pre、data 和 next 域外,还有一个访问频度域 freq,其值均初始化为零。每当在链表中进行一次 Locate(L,x)运算时,令值为x的结点中 freg 域的值增1,并使此链表中的结点保持按访问频度递减的顺序排列,且最近访问的结点排在频度相同的结点之前,以便使频繁访问的结点总是靠近表头。试编写符合上述要求的 Locate(L,x)函数,返回找到结点的地址,类型为指针型。
//用于查找值为 x 的节点,并更新其访问频度。若找到节点,则将其移动到合适的位置以保持频度递减的顺序。时间复杂度为O(n),空间复杂度为O(1)
DNode* Locate(DNode* L, int x) {
    DNode* p = L->next; // 从头结点的下一个开始
    DNode* q;
    // 找到值为x的节点
    while (p && p->data != x) {
        p = p->next;
    }
    if (p == NULL) { // x不存在
        return p;
    } else {
        p->freq++; // 增加访问频度
        // 如果p是头结点的下一个或p的前一个节点的频度大于p的频度
        if (p->pre == L || p->pre->freq > p->freq) {
            return p; // 不需要移动
        }
        q = p->pre;
        // 如果p不是最后一个节点
        if (p->next != NULL) {
            p->next->pre = q;
            q->next = p->next;
        } else {
            q->next = p->next;    //是最后一个节点
        }
        // 找到插入位置
        while (q != L && p->freq <= q->freq) {
            q = q->next;
        }
        // 插入p到q之后
        p->next = q->next;
        if (q->next != NULL) {
            q->next->pre = p;
        }
        q->next = p;
        p->pre = q;
        return p;
    }
}
//	58.单链表有环,是指单链表的最后一个结点的指针指向了链表中的某个结点(通常单链表的最后一个结点的指针域是空的)。试编写算法判断单链表是否存在环。
//最优解
//使用快慢指针法判断链表是否存在环。如果快指针和慢指针相遇,则说明存在环。时间复杂度为O(n),空间复杂度为O(1)
int fun(Linklist L){
	LNode *fast=L,*slow=L;
	while(fast->next != NULL && fast != NULL){
		slow=slow->next;
		fast=fast->next->next;
		if(slow==fast){
			return 1;
		}
	}
	return 0;
} 
//暴力解
int fun(Linklist L){
	LNode *pre=L,*p=L;
	while(p){
		while(pre!=p){
			if(p->next == pre){
				return 1;
			}
			pre=pre->next;
		}
		p=p->next;
		pre=L;
	}
	return 0;
} 

//	59.设有一个长度 n(n 为偶数)的不带头结点的单链表,且结点值都大于 0,设计算法求这个单链表的最大孪生和。孪生和定义为一个结点值与其孪生结点值之和,对于第i个结点(从开始),其孪生结点为第 n-i个结点。
//该算法首先找到链表的中点,然后反转后半部分链表,最后计算每对孪生节点的和并找出最大值。时间复杂度为O(n),空间复杂度为O(1)   反转用头插 
int fun(Linklist L){
	LNode *fast=L,*slow=L;
	while(fast->next && fast){
		slow=slow->next;
		fast=fast->next->next;
	} 
	Lnode *newhead=NULL,*r;
	while(s){
		r=s->next;
		s->next=newhead;
		newhead=s;
		s=r;
	}
	p=L;
	Lnode *Q=newheaf;
	int max=0;
	while(p){
		if(p->data+q->data>max){
			max=p->data+q->data;
			p=p->next;
			q=q->next;
		}
	}
	return max;
}

//	60.已知一个带有表头结点的单链表,结点结构为 data,next 假设该链表只给出了头指针 L在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k 为正整数)。若查找成功,算法输出该结点的 data 域的值,并返回 1:否则,只返回 0.
//	该算法使用两个指针,p 和 q,在遍历链表时保持 p 比 q 领先 k 个节点。最终,当 p 到达链表末尾时,q 就是倒数第k个节点。时间复杂度为O(n),空间复杂度为O(1)
int fun(Linklist L,int k){
	LNode *p=L->next,*q=L->next;
	int count=0;
	while(p){
		if(count<k){
			p=p->next;
			count++;
		}
		else{
			p=p->next;
			q=q->next;
		}
	}
	if(count<k){
		return 0;
	} else{
		printf("%d",q->data);
		return 1;
	}
}


	return 0;
} 
相关推荐
昨天今天明天好多天2 分钟前
【Mac】Python 环境管理工具
开发语言·python·macos
西瓜本瓜@10 分钟前
在Android开发中实现静默拍视频
android·java·开发语言·学习·音视频
_.Switch14 分钟前
高效网络自动化:Python在网络基础中的应用
运维·开发语言·网络·python·数据分析·自动化
清灵xmf23 分钟前
JavaScript 中如何识别异步函数?
开发语言·javascript·async·异步函数
七月巫山晴40 分钟前
QChart中柱形图的简单使用并实现【Qt】
开发语言·数据结构·c++·qt·算法·排序算法
阿丁小哥42 分钟前
【Python各个击破】numpy
开发语言·python·numpy
琼火hu1 小时前
R语言笔记(五):Apply函数
开发语言·笔记·r语言·apply
一个不喜欢and不会代码的码农1 小时前
力扣1381:设计一个支持增量操作的栈
数据结构·算法·leetcode
柴头物联网1 小时前
XQT_UI 组件|01|颜色
开发语言·qt·ui
浪漫主义狗1 小时前
JDK源码系列(二)—— ArrayList 和 LinkedList 深度源码解析
java·开发语言·windows·源码