链表--一个带头结点的单链表,按递增次序输出单链表中各结点的数据元素,并释放结点所占的存储空间。(要求:不允许使用数组作为辅助空间)

#include <stdio.h>
#include <stdlib.h>

typedef int ElemType;
typedef struct LNode{
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;

void Min_print(LinkList L){
	LNode *p,*q,*pre;
	while(L->next){
		pre=L;
		p=L->next;
		while(p->next){ //这里用p->next其实和冒泡排序内层循环,j和j+1比较,j不用走到最后就已经完成了全部比较。
			if(p->next->data<p->data)
				pre=p;	//链表的删除操作,需要用到前一个结点,避免断链
			p=p->next;
		}
		printf("%d",pre->next->data);
		q=pre->next;
		pre->next=q->next;
		free(q);
	}
	free(L); //最后不要忘记free掉头结点
}

把这道题拿出来是因为不许使用辅助空间,链表这边的题:
1.只提到高效这个要求的,就要考虑到应用辅助空间。
2.不让使用辅助空间的时候,基本就是可以不用考虑时间复杂度。
3.提到高效又尽可能省空间的,基本就是在链表上做操作了,要么是快慢指针,要么是链表就地逆置,也可能是快慢指针配合链表就地逆置。保证空间复杂度在O(1),时间复杂度在O(n)。

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
一、查找 1. 算法设计题 :已知n元顺序表a0, a1, … , an-1按关键字递增有序存储。给定关键字值key,编写算法用对分查找求下标i,满足ai-1<key且aikey。 2. 编程题:输入n个两两互不相等的整数,以这些整数为关键字建立平衡的二叉排序树。判断该二叉树是否为平衡的,输出判断结果;输出该二叉树的序遍历关键字访问次序。 3. 从空树起连续插入以下20个关键字构建m=4的B-树。 50, 15, 09, 18, 03, 85, 33, 72, 48, 22, 91, 88, 11, 99, 06, 56, 68, 77, 43, 36。 4. 16个关键字组成的5阶B-树如下图所示,请按关键 字递减的次序删除所有结点至空树,画出每删除1个关键字后得到B-树,直至空树。 5. 12个关键字如本电子教案例1所示,设H(K)=K mod 13,地址空间范围0~15,用二次探测再散列解决冲突。画出哈希表;若各元素等概率查找,求成功查找时的平均查找长度。 二、内部排序 1.算法设计与分析题:将直接插入排序的内循环改造为使用对分查找实现元素插入,请写出基于对分查找的插入排序算法并给出其时间复杂度分析。 2.算法设计:将教案给出的非递归直接插入排序和冒泡排序算法用递归算法实现。 3.算法设计:附加头结点单链表将各数据结点按关键字升序连接。 4.编程题:键盘输入n个无符号整数,用链式基数排序实现由小到大排序,输出排序结果。 提示:对于C语言32bit宽的unsigned类型,可以采用16进制形式来实现基数排序,即32bit共有8个16进制位,每个16进制位进行一趟分配和收集,共8趟。
西南交大;西南交通大学;数据结构;赵宏宇;一、二叉树(二) 1. 写算法 (1) 二叉树的直径定义为从根结点至叶子的最大路径长度。编写算法,求二叉树(二叉链表)的直径。 (2) 已知二叉树(二叉链表)根结点指针bt,树两个结点的指针p、q。编写算法求距离结点*p和*q最近的公共祖先的地址。 (3) 已知二叉树(二叉链表)根结点指针bt,利用二叉树叶子结点的rchild指针域将所有叶子结点从左向右连接成一个单向链表。算法返回单向链表头结点指针(即最左边第1个叶子结点的地址)。 2. 编程题 (1) 从键盘输入一个字符串(要求字符串无重复字符),将串字符当做完全二叉树的顺序存储结构,建立对应的完全二叉树的二叉链表存储结构,输出先、、后序遍历结果。 (2) 用先序遍历法建立二叉树二叉链表存储结构(结点数据域类型为char,输入字符序列用字符'#'表示NULL),实现序线索化,并用非递归算法输出序遍历结果的正序和逆序序列。 二、图 1. 已知某无向图如下图所示。画出该图的多重邻接表存储结构示意图。根据该存储结构,写出从顶点v0出发,深度和宽度优先遍历顶点访问次序。 2. 写一个算法,判断无向图是否有环。算法提要:深度优先遍历过程,访问某顶点后,该顶点的邻接点有已访问的顶点且该已访问邻接点不是该顶点的上一级递归出发顶点(即存在回边),则有环。 3. 编程题: 建立无向图邻接表存储结构,输出深度和宽度优先遍历顶点访问次序。 4. 编程题:建立AOE网络存储结构,计算并输出ve[]和vl[]。 5. 选作题*:算法设计-已知AOE网络的邻接表存储结构G,ve[]和vl[]值已全部求取,写出算法,输出所有关键路径。要求每条关键路径用源点至汇点的顶点序列(拓扑有序)表示。
### 回答1: 算法步骤如下: 1. 定义三个指针:p1指向第一个单链表头结点,p2指向第二个单链表头结点,p3指向归并后的单链表头结点(初始为空)。 2. 比较p1和p2指向的结点的值,将较小的结点插入到p3指向的单链表的头部,并将p3指向新插入的结点。 3. 重复步骤2,直到p1或p2指向的链表为空。 4. 将p1或p2指向的链表剩余的结点插入到p3指向的单链表的头部。 5. 返回归并后的单链表头结点。 代码实现如下: ```python def merge(l1, l2): p1, p2, p3 = l1, l2, None if p1.val <= p2.val: p3 = p1 p1 = p1.next else: p3 = p2 p2 = p2.next while p1 and p2: if p1.val <= p2.val: p3.next = p1 p1 = p1.next else: p3.next = p2 p2 = p2.next p3 = p3.next if p1: p3.next = p1 else: p3.next = p2 return l1 if l1.val >= l2.val else l2 ``` 其,l1和l2分别为两个单链表头结点。 ### 回答2: 归并两个单链表的基本思路是,比较两个单链表的首元素,将较小的元素插入新的单链表,然后原单链表的节点指针向后移动,继续比较,直到一个单链表的节点遍历完毕,将另一个单链表的剩余元素插入新的单链表。 本题要求将两个按元素递增次序排列的单链表归并为一个元素值递减次序排列的单链表,即每次比较找到较小的元素时,要将其插入新链表的表头,而不是表尾。 首先,定义一个空的单链表,作为归并后的单链表。然后建立三个指针p,q,r分别指向两个原单链表的首节点和新单链表的首节点。 接下来,进行循环遍历,比较p和q指向的节点的大小,找到较小的节点插入r指向的新单链表,然后将p或q指向下一个节点,r指向刚插入的节点。直到有一个单链表全部遍历完毕为止。此时,将另一个单链表剩余的节点插入r指向的新单链表的表头位置即可。 具体的过程可以这样实现: ``` // 归并两个单链表一个递减排序单链表,并利用原节点存储结果 void merge(LinkList &L1, LinkList &L2) { LinkList L = (LinkList) malloc(sizeof(Node)); // 归并后的单链表 L->next = NULL; Node *p = L1->next, *q = L2->next, *r; while (p && q) { if (p->data <= q->data) { r = p; p = p->next; } else { r = q; q = q->next; } r->next = L->next; L->next = r; } if (p) { // L1未遍历完,将剩余节点插入L的表头 p->next = L->next; L->next = p; } if (q) { // L2未遍历完,将剩余节点插入L的表头 q->next = L->next; L->next = q; } L1->next = NULL; L2->next = NULL; p = L->next; while (p) { // 将归并后的单链表放回两个原链表存储空间 r = p->next; p->next = L1->next; L1->next = p; p = r; } free(L); // 释放辅助单链表空间 } ``` 其,LinkList是指向头节点的指针,Node是单链表节点的结构体,包含data和next两个成员。在归并后,我们将新单链表放回L1和L2,利用原有空间存储结果,这样可以节省空间,不需要重新申请空间来存储新的单链表。最后,别忘了释放辅助单链表空间,避免内存泄漏。 ### 回答3: 题目要求我们将两个按元素递增次序排列的单链表合并为一个元素值递减次序排列的单链表,并且要利用原来的两个单链表结点来存放合并后的单链表。 首先,我们可以设定两个指针指向两个单链表的头节点,一个指针用于遍历第一个单链表,另一个指针用于遍历第二个单链表,并设置一个新的头节点指针用于记录归并后的单链表的头节点。 然后,我们比较两个指针所指节点的值的大小,将较大值的节点作为新的单链表的头节点,并将该节点的指针指向较小值的指针所指节点。接着,我们将指向较小值的指针向后移动一个位置,继续比较两个指针所指节点的值的大小,重复以上步骤直到遍历完其一个单链表。最后,我们将剩余的节点全部添加到新的单链表即可。 需要注意的是,由于是按递减排列节点的顺序,所以我们需要将新节点插入到新单链表的头节点位置。 具体实现步骤如下: 1. 定义两个指针指向两个单链表的头节点,并设置一个新的头节点指针记录归并后的单链表的头节点。 2. 比较两个指针所指节点的值的大小,将较大值的节点作为新的单链表的头节点,并将该节点的指针指向较小值的指针所指节点。 3. 将指向较小值的指针向后移动一个位置,继续比较两个指针所指节点的值的大小,重复以上步骤直到遍历完其一个单链表。 4. 将剩余的节点全部添加到新的单链表。 5. 返回新的头节点指针。 代码实现如下: ```python def merge_list(list1, list2): # 定义两个指针指向两个单链表的头节点 p1 = list1.head p2 = list2.head # 设置一个新的头节点指针记录归并后的单链表的头节点 result = Node(0) # 定义一个指针指向新的单链表的头节点 p = result # 遍历两个链表,将较大值的节点作为新的单链表的头节点 while p1 and p2: if p1.value > p2.value: # 将较大值的节点作为新的单链表的头节点 p.next = p1 p1 = p1.next else: # 将较大值的节点作为新的单链表的头节点 p.next = p2 p2 = p2.next # 将指向较小值的指针向后移动一个位置 p = p.next # 将剩余的节点全部添加到新的单链表 p.next = p1 if p1 else p2 # 返回新的头节点指针 return result.next ``` 以上就是将两个按元素递增次序排列的单链表合并为一个元素值递减次序排列的单链表的具体实现方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值