排序常用算法设计

合集下载

软件设计师常考算法知识点

软件设计师常考算法知识点

软件设计师常考算法知识点在软件设计师岗位的面试过程中,算法知识是常常考察的一个重要方面。

算法作为计算机科学的基础,是软件设计师必不可少的技能之一。

下面将介绍一些软件设计师常考的算法知识点。

一、排序算法1. 冒泡排序冒泡排序是一种简单的交换排序算法,通过重复遍历待排序序列,比较相邻元素并交换位置来实现排序。

具体步骤如下:(1)比较相邻的两个元素,如果前者大于后者,则交换位置;(2)重复步骤(1),直到遍历完整个序列,此时最大的数会被移到最后一位;(3)重复步骤(1)和(2),直到所有元素都排序完成。

2. 快速排序快速排序是一种常见的基于“分治”思想的排序算法,通过递归地将待排序序列划分为较小和较大的两个子序列,再分别对子序列进行排序。

具体步骤如下:(1)选择一个基准元素,通常选择第一个元素;(2)将比基准元素小的元素移到基准元素的左边,比基准元素大的元素移到右边;(3)对左右子序列分别重复步骤(1)和(2),直到所有元素排序完成。

二、查找算法1. 二分查找二分查找是一种高效的查找算法,要求待查找的序列必须是有序的。

具体步骤如下:(1)选择序列的中间元素;(2)如果中间元素等于目标值,则查找成功;(3)如果中间元素大于目标值,则在左侧子序列中继续进行二分查找;(4)如果中间元素小于目标值,则在右侧子序列中继续进行二分查找;(5)重复步骤(1)至(4),直到找到目标值或遍历完整个序列。

2. 哈希查找哈希查找是通过哈希函数将要查找的元素映射到一个位置,进而直接访问该位置的元素来实现查找。

具体步骤如下:(1)构建一个哈希表,将元素与对应的位置进行关联;(2)根据哈希函数将要查找的元素映射到哈希表中的某个位置;(3)如果该位置存在元素,则查找成功;(4)如果该位置不存在元素,则查找失败。

三、图算法1. 广度优先搜索广度优先搜索是一种用于图的遍历的算法,通过逐层扩展访问顶点,直到遍历完所有与起始顶点连通的顶点。

排序算法设计实验报告

排序算法设计实验报告

一、实验目的1. 理解排序算法的基本原理和常用算法。

2. 通过编程实现几种常见的排序算法。

3. 分析不同排序算法的性能,比较其优缺点。

4. 培养编程能力和算法思维能力。

二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.73. 开发工具:PyCharm三、实验内容1. 算法选择:冒泡排序、选择排序、插入排序、快速排序、归并排序2. 实现排序算法3. 分析算法性能4. 比较不同排序算法的优缺点四、实验步骤1. 设计排序算法(1)冒泡排序冒泡排序是一种简单的排序算法,其基本思想是通过比较相邻元素的值,将较大的元素向后移动,较小的元素向前移动,直到整个序列有序。

(2)选择排序选择排序的基本思想是遍历整个序列,在未排序的序列中找到最小(大)元素,将其与序列的第一个元素交换,然后继续在剩余未排序的序列中找到最小(大)元素,重复此过程,直到整个序列有序。

(3)插入排序插入排序的基本思想是将未排序的序列中的元素插入到已排序的序列中,直到整个序列有序。

(4)快速排序快速排序是一种高效的排序算法,其基本思想是选取一个基准值,将序列分为两部分,一部分小于基准值,另一部分大于基准值,然后递归地对这两部分进行快速排序。

(5)归并排序归并排序是一种分治策略的排序算法,其基本思想是将序列划分为两个子序列,分别对这两个子序列进行排序,然后将排序好的子序列合并为一个有序序列。

2. 编写排序算法代码```pythondef bubble_sort(arr):n = len(arr)for i in range(n):for j in range(0, n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]def selection_sort(arr):n = len(arr)for i in range(n):min_idx = ifor j in range(i+1, n):if arr[min_idx] > arr[j]:min_idx = jarr[i], arr[min_idx] = arr[min_idx], arr[i]def insertion_sort(arr):n = len(arr)for i in range(1, n):key = arr[i]j = i-1while j >= 0 and key < arr[j]:arr[j+1] = arr[j]j -= 1arr[j+1] = keydef quick_sort(arr):if len(arr) <= 1:return arrpivot = arr[len(arr) // 2]left = [x for x in arr if x < pivot]middle = [x for x in arr if x == pivot]right = [x for x in arr if x > pivot]return quick_sort(left) + middle + quick_sort(right) def merge_sort(arr):if len(arr) <= 1:return arrmid = len(arr) // 2left = merge_sort(arr[:mid])right = merge_sort(arr[mid:])return merge(left, right)def merge(left, right):result = []i = j = 0while i < len(left) and j < len(right):if left[i] < right[j]:result.append(left[i])i += 1else:result.append(right[j])j += 1result.extend(left[i:])result.extend(right[j:])return result```3. 分析算法性能(1)冒泡排序冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1)。

单片机常用算法设计详解

单片机常用算法设计详解

单片机常用算法设计详解一、排序算法排序是将一组数据按照特定的顺序进行排列的过程。

在单片机中,常见的排序算法有冒泡排序、插入排序和快速排序。

冒泡排序是一种简单直观的排序算法。

它通过反复比较相邻的两个元素,如果顺序不对则进行交换,直到整个数组有序。

这种算法的优点是实现简单,容易理解,但效率较低,对于大规模数据的排序不太适用。

插入排序的基本思想是将待排序的元素插入到已经有序的部分中。

它从第二个元素开始,将其与前面已排序的元素进行比较,并插入到合适的位置。

插入排序在小规模数据时表现较好,但其平均和最坏情况下的时间复杂度不如快速排序。

快速排序则是一种高效的排序算法。

它选择一个基准元素,将数组分为小于和大于基准元素的两部分,然后对这两部分分别进行快速排序。

快速排序在大多数情况下具有较好的性能,但在最坏情况下可能会退化为 O(n²)的时间复杂度。

在单片机中选择排序算法时,需要根据数据规模和对时间效率的要求进行权衡。

二、查找算法查找是在一组数据中寻找特定元素的过程。

常见的查找算法有顺序查找和二分查找。

顺序查找是从数组的开头依次比较每个元素,直到找到目标元素或遍历完整个数组。

它适用于数据无序的情况,但效率较低。

二分查找则要求数组必须是有序的。

通过不断将数组中间的元素与目标元素进行比较,缩小查找范围,直到找到目标元素。

二分查找的时间复杂度为 O(log n),效率较高,但需要数据有序。

在单片机应用中,如果数据经常需要查找且能保持有序,应优先考虑二分查找。

三、数据压缩算法在单片机系统中,为了节省存储空间和传输带宽,常常需要使用数据压缩算法。

常见的数据压缩算法有哈夫曼编码和 LZW 编码。

哈夫曼编码是一种无损数据压缩算法。

它根据字符出现的频率构建一棵哈夫曼树,然后为每个字符生成唯一的编码。

频率高的字符编码较短,频率低的字符编码较长,从而实现数据压缩。

LZW 编码则是一种字典编码算法。

它通过建立一个字典,将重复出现的字符串用较短的编码表示,从而达到压缩的目的。

程序设计中常用的排序算法

程序设计中常用的排序算法
rt m us be c osn whe e tdelo r i o e n o de o s e h ro a eofpr g a ih m t h e n a g a a fa ebeng s r d i r rt pe d up t e pef r nc o mm i . r t m r ng
维普资讯

研 究 开 发 ・ ・ ・ ・ ・
电 脑 知 识 与 技 术
程序 设计 中常用 的排序 算法
刘艳荣 ’
(. 津 大 学 电信 学 院 , 津 30 7 :. 顺 市 第 一 中等 职 业技 术 专 业 学 校 , 宁 抚 顺 13 0 ) 1天 天 0 0 22 抚 辽 10 6
(.i J ie i l t ncIfr t nE gne n ,i J 0 0 2C i ;. efspoes nlco l fh cu ao cnq en 1 a i Un rt Ee r i nomao n ier g a i 3 07 ,hn 2t r rf i ash o o eocpt nt hiu T nn v sy co i i T nn a h it so t i e i F su , su 0 6 ia uh nF h n13 0 , n) u 1 Ch
中图分类号 : P 1 T 32
文献标识码 : A
文章编号 :0 9 3 4 (0 62 — 1 6 O 1 0 — 0 42 0 )9 0 0 一 1
LU a 1 Y n—r ng・ o 。
Co mo rn g i ms i 0 r mm ig m n Sot g Alorh n Prg a i t n
cu ig i srin s r, h l s r, e p s r m eg o ,b b l s r, u c o , swela h i e c mp e i fe c lo t m.Th p l o ld n e o o S el o h a o , r e s r u b e o q ik s r a l st e t o l t o a h ag r h n t t t t t t t m xy i ea t g — a

数据排序教学设计

数据排序教学设计

数据排序教学设计教学设计:数据排序一、教学目标:1. 理解数据排序的概念和意义;2. 掌握常见的数据排序算法,包括冒泡排序、选择排序和插入排序;3. 能够通过编程实现数据排序算法;4. 能够分析和比较不同排序算法的时间复杂度和空间复杂度。

二、教学内容:1. 数据排序的概念和意义:数据排序是将一组无序的数据按照一定的规则进行重新排列的过程。

排序能够提高数据的查找和处理效率,是计算机科学中非常重要的基本操作。

2. 常见的数据排序算法:a. 冒泡排序:冒泡排序是一种简单的排序算法,它重复地遍历要排序的数据,比较相邻的两个元素,如果顺序错误就交换它们。

通过多次遍历,将最大(或最小)的元素逐渐移动到最后,直到所有元素都有序。

示例代码:```def bubble_sort(arr):n = len(arr)for i in range(n-1):for j in range(n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]return arr```b. 选择排序:选择排序是一种简单直观的排序算法,它的基本思想是每次从待排序的数据中选择最小(或最大)的元素,放到已排序序列的末尾,直到所有元素都有序。

示例代码:```def selection_sort(arr):n = len(arr)for i in range(n-1):min_index = ifor j in range(i+1, n):if arr[j] < arr[min_index]:min_index = jarr[i], arr[min_index] = arr[min_index], arr[i]return arr```c. 插入排序:插入排序是一种简单直观的排序算法,它的基本思想是将待排序的数据分成已排序和未排序两部分,每次从未排序部分取出一个元素,插入到已排序部分的合适位置,直到所有元素都有序。

程序设计竞赛常用算法

程序设计竞赛常用算法

程序设计竞赛常用算法1.排序算法:排序是一个基本的算法问题,常见的排序算法有冒泡排序、选择排序、插入排序、快速排序、归并排序等。

这些排序算法有各自的优势和适用场景,需要根据具体问题需求选择合适的算法。

2.图论算法:图论是程序设计竞赛中经常出现的重要领域。

常见的图论算法有深度优先(DFS)、广度优先(BFS)、Dijkstra算法、Floyd-Warshall算法、拓扑排序、最小生成树等。

这些算法可以用于解决最短路径、连通性、最大流最小割等问题。

3.动态规划:动态规划是一种常用于解决优化问题的算法。

该算法通过将问题分解成子问题,并记录子问题的解来求解原问题的最优解。

常见的动态规划算法有背包问题、最长公共子序列(LCS)、最大子序列和等。

4.字符串处理算法:字符串处理是程序设计竞赛中常见的问题。

常见的字符串处理算法有KMP算法、哈希算法、字符串匹配等。

这些算法可以用于解决模式匹配、字符串、字符统计等问题。

5.数学算法:数学算法在程序设计竞赛中也经常被使用。

常见的数学算法有质因数分解、素数筛、快速乘法、高精度计算等。

这些算法可以用于解决数论、计算几何、概率等问题。

6.图形算法:图形算法主要用于处理图像和几何图形。

常见的图形算法有扫描线算法、凸包算法、几何运算等。

这些算法可以用于解决图像处理、三维建模等问题。

7.树和图的遍历算法:树和图的遍历算法是程序设计竞赛中常用的算法之一、常见的树和图的遍历算法有先序遍历、中序遍历、后序遍历、深度优先(DFS)、广度优先(BFS)等。

这些算法可以用于解决树和图的构建、路径等问题。

8.最大匹配和最小割算法:最大匹配算法用于求解二分图的最大匹配问题,常见的算法有匈牙利算法。

最小割算法用于求解图的最小割问题,常见的算法有Ford-Fulkerson算法。

这些算法可以用于解决网络流和二分图匹配等问题。

9.贪心算法:贪心算法是一种常用于优化问题的算法。

该算法通过每一步选择局部最优解来达到全局最优解。

算法分析与设计实验报告合并排序快速排序

算法分析与设计实验报告合并排序快速排序

算法分析与设计实验报告:合并排序与快速排序一、引言算法是计算机科学中非常重要的一部分,它涉及到解决问题的方法和步骤。

合并排序和快速排序是两种经典而常用的排序算法。

本文将对这两种排序算法进行分析和设计实验,通过对比它们的性能和效率,以期得出最优算法。

二、合并排序合并排序是一种分治算法,它将原始数组不断分解为更小的数组,直到最后细分为单个元素。

然后,再将这些单个元素两两合并,形成一个有序数组。

合并排序的核心操作是合并两个有序的数组。

1. 算法步骤(1)将原始数组分解为更小的子数组,直到每个子数组只有一个元素;(2)两两合并相邻的子数组,同时进行排序,生成新的有序数组;(3)重复步骤(2),直到生成最终的有序数组。

2. 算法性能合并排序的最优时间复杂度为O(nlogn),其中n为待排序数组的长度。

无论最好情况还是最坏情况,合并排序的复杂度都相同。

合并排序需要额外的存储空间来存储临时数组,所以空间复杂度为O(n)。

三、快速排序快速排序也是一种分治算法,它将原始数组根据一个主元(pivot)分成两个子数组,一个子数组的元素都小于主元,另一个子数组的元素都大于主元。

然后,递归地对这两个子数组进行排序,最后得到有序数组。

快速排序的核心操作是划分。

1. 算法步骤(1)选择一个主元(pivot),可以是随机选择或者固定选择第一个元素;(2)将原始数组根据主元划分为两个子数组,一个子数组的元素都小于主元,另一个子数组的元素都大于主元;(3)递归地对这两个子数组进行快速排序;(4)重复步骤(2)和(3),直到每个子数组只有一个元素,即得到最终的有序数组。

2. 算法性能快速排序的平均时间复杂度为O(nlogn),其中n为待排序数组的长度。

最坏情况下,当每次选择的主元都是最小或最大元素时,时间复杂度为O(n^2)。

快速排序是原地排序,不需要额外的存储空间,所以空间复杂度为O(1)。

四、实验设计为了验证合并排序和快速排序的性能和效率,我们设计以下实验:1. 实验目的:比较合并排序和快速排序的时间复杂度和空间复杂度。

各种排序算法的课程设计

各种排序算法的课程设计

各种排序算法的课程设计一、课程目标知识目标:1. 让学生掌握排序算法的基本概念,了解不同排序算法的优缺点及应用场景。

2. 使学生能够理解和掌握冒泡排序、选择排序、插入排序等基本排序算法的原理和实现方法。

3. 帮助学生理解排序算法的时间复杂度和空间复杂度,并能够分析不同算法的效率。

技能目标:1. 培养学生运用编程语言实现排序算法的能力,提高编程实践操作技能。

2. 培养学生通过分析问题,选择合适的排序算法解决实际问题的能力。

情感态度价值观目标:1. 激发学生对计算机科学和算法的兴趣,培养主动探究和自主学习的精神。

2. 培养学生面对问题时的耐心和细心,提高解决问题的信心和团队合作意识。

3. 使学生认识到排序算法在生活中的广泛应用,体会算法对人类社会的贡献。

课程性质分析:本课程为计算机科学相关学科,旨在让学生掌握排序算法的基本原理和实现方法,提高编程实践能力。

学生特点分析:学生处于年级中段,具有一定的编程基础和逻辑思维能力,对新鲜事物充满好奇心,但学习耐心和自律性有待提高。

教学要求:1. 注重理论与实践相结合,提高学生的实际操作能力。

2. 通过案例分析,引导学生主动思考,提高问题解决能力。

3. 创设互动、轻松的学习氛围,关注学生个体差异,激发学习兴趣。

二、教学内容1. 排序算法基本概念:介绍排序的定义、排序算法的稳定性、内排序与外排序的分类。

2. 冒泡排序:讲解冒泡排序的原理、实现步骤,分析其时间复杂度和空间复杂度。

3. 选择排序:介绍选择排序的原理、实现步骤,分析其时间复杂度和空间复杂度。

4. 插入排序:讲解插入排序的原理、实现步骤,分析其时间复杂度和空间复杂度。

5. 排序算法比较:对比冒泡排序、选择排序和插入排序的优缺点,探讨在不同场景下如何选择合适的排序算法。

6. 教学案例:结合实际案例,让学生动手实践排序算法,提高编程能力。

7. 排序算法拓展:简要介绍其他常用排序算法(如快速排序、归并排序等)的原理和应用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第8 章排序(算法设计)习题练习答案13. 将哨兵放在R[n]中,被排序的记录放在R[0..n-1]中,重写直接插入排序算法。

解:重写的算法如下:void InsertSort(SeqList R){//对顺序表中记录R[0..n-1]按递增序进行插入排序int i,j;for(i=n-2;i>=0;i--) //在有序区中依次插入R[n-2]..R[0]课后答案网if(R[i].key>R[i+1].key) //若不是这样则R[i]原位不动{R[n]=R[i];j=i+1; //R[n]是哨兵do{ //从左向右在有序区中查找插入位置R[j-1]=R[j]; //将关键字小于R[i].key 的记录向右移j++;}while(R[j].key<R[n].key]);R[j-1]=R[n]; //将R[i]插入到正确位置上}//endif}//InsertSort.14.以单链表作为存储结构实现直接插入排序算法。

解:#define int KeyType //定义KeyType 为int 型typedef struct node{KeyType key; //关键字域OtherInfoType info; //其它信息域,struct node * next; //链表中指针域}RecNode; //记录结点类型typedef RecNode * LinkList ; //单链表用LinkList 表示void InsertSort(LinkList head){//链式存储结构的直接插入排序算法,head 是带头结点的单链表RecNode *p,*q,*s;if ((head->next)&&(head->next->next))//当表中含有结点数大于1 {p=head->next->next;//p 指向第二个节点head->next=NULL;q=head;//指向插入位置的前驱节点while(p)&&(q->next)&&(p->key<q->next->key)q=q->next;if (p)课后答案网{s=p;p=p->next;// 将要插入结点摘下s->next=q->next;//插入合适位置:q 结点后q->next=s;}}}15.设计一算法,使得在尽可能少的时间内重排数组,将所有取负值的关键字放在所有取非负值的关键字之前。

请分析算法的时间复杂度。

解:因为只需将负数关键字排在前面而无需进行精确排列顺序,因此本算法采用两端扫描的方法,就象快速排序采用的方法一样,左边扫描到正数时停止,开始扫描右边,遇到负数时与左边的当前记录交换,如此交替进行,一趟下来就可以完成排序。

void ReSort(SeqList R){//重排数组,使负值关键字在前int i=1,j=n; //数组存放在R[1..n]中while (i<j) //i<j 表示尚未扫描完毕{ while(i<j&&R[i].key<0) //遇到负数则继续扫描i++;R[0]=R[i]; //R[0]为辅助空间while(i<j&&R[j].key>=0)// 遇到正数则继续向左扫描j--;R[i++]=R[j];R[j--]=R[0];//交换当前两个元素并移动指针}//endwhile}//ReSort本算法在任何情况下的比较次数均为n(每个元素和0)相比,交换次数少于n/2,总的来说,时间复杂度为O(n).*16.写一个双向冒泡排序的算法,即在排序过程中交替改变扫描方向。

解:算法如下:void BubbleSort(SeqList R)课后答案网{//R[1..n]是待排序文件,双向扫描冒泡排序int i,j,k;Boolean exchange; //交换标记i=n;j=1;exchange=TRUE;while (i>j)&&(exchange){k=i-1;exchange=FALSE;while (k>=j)//由下往上扫描{if (r[k]>r[k+1]){r[0]=r[k];r[k]=r[k+1];r[k+1]=r[k];exchange=TRUE;//交换}//endifk--;}//endwhileif (exchange){exchange=FALSE;j++;k=j+1;while(k<=i)//由上往下扫描{if (r[k]<r[k-1]){r[0]=r[k];r[k]=r[k-1];r[k-1]=r[k];exchange=TRUE;//交换}//endifk++;}endwhilei--;}//endif}endwhile}//endsort17.下面是一个自上往下扫描的冒泡排序的伪代码算法,它采用lastExchange 来记录每趟扫描中进行交换的最后一个元素的位置,并以它作为下一趟排序循环终止的控制值。

请仿照它写一个自下往上扫描的冒泡排序算法。

课后答案网void BubbleSort(int A[],int n)//不妨设A[0..n-1]是整型向量int lastExchange,j,i=n-1;while (i>0)lastExchange=0;for(j=0;j<i;j++)//从上往下扫描A[0..i]if(A[j+1]<A[j]){交换A[j]和A[j+1];lastExchange=j;}i=lastExchange;//将i 置为最后交换的位置}//endwhile}//BubbleSort解:算法如下:void BubbleSort(int A[],int n)//不妨设A[0..n-1]是整型向量int lastExchange,j,i=0;while (i<n) //这一条很重要,如不改为这样,算法将无限循环下去lastExchange=n;for(j=n-1;j>i;j--)//从下往上扫描A[0..i]if(A[j-1]<A[j]){交换A[j]和A[j-1];lastExchange=j;}i=lastExchange;//将i 置为最后交换的位置}//endwhile}//BubbleSort18.改写快速排序算法,要求采用三者取中的方式选择划分的基准记录;若当前被排序的区间长度小于等于3 时,无须划分而是直接采用直接插入方式对其排序。

课后答案网解:改写后的算法如下:void QuickSort(SeqList R,int low ,int high){//对R[low..high]快速排序int pivotpos;if(high-low<=2)//若当前区内元素少于3 个{//则进行直接插入排序InsertSort(R,low,high);}else{pivotpos=midPartion(R,low,high);QuickSort(R,low,pivotpos-1);QuickSort(R,pivotpos+1,high);}}//QuickSortint midPartion(SeqList R,int i, int j){//三者取中规则定基准if(R[(i+j)/2].key>R[i].key){ 交换R[(i+j)/2]和R[i];}if(R[i].key>R[j].key){ 交换R[i]和R[j];}if(R[i].key)<R[(i+j)/2].key){ 交换R[i]和R[(i+j)/2];}//以上三个if 语句就使区间的第一个记录的key 值为三个key 的中间值return Partion(R,i,j);//这样我们就可以仍使用原来的划分算法了}19.对给定的j(1≤j≤n ),要求在无序的记录区R[1..n]中找到按关键字自小到大排在第j个位置上的记录(即在无序集合中找到第j 个最小元),试利用快速排序的划分思想编写算法实现上述的查找操作。

课后答案网答:int QuickSort(SeqList R,int j,int low,int high){ //对R[low..high]快速排序int pivotpos;//划分后的基准记录的位置if(low<high){//仅当区间长度大于1 时才须排序pivotpos=Partition(R,low,high);//对R[low..high]做划分if (pivotpos==j) return r[j];else if (pivotpos>j) return(R,j,low,pivotpos-1);else return quicksort(R,j,pivotpos+1,high);}} //QuickSort20.以单链表为存储结构,写一个直接选择排序算法。

答:#define int KeyType //定义KeyType 为int 型typedef struct node{KeyType key; //关键字域OtherInfoType info; //其它信息域,struct node * next; //链表中指针域}RecNode; //记录结点类型typedef RecNode * LinkList ; //单链表用LinkList 表示void selectsort(linklist head){RecNode *p,*q,*s;if(head->next)&&(head->next->next){p=head->next;//p 指向当前已排好序最大元素的前趋while (p->next){q=p->next;s=p;while(q){if (q->key<s->key) s=q;q=q->next;}//endwhile交换s 结点和p 结点的数据;课后答案网p=p->next;}//endwhile}//endif}//endsort21.写一个heapInsert(R,key)算法,将关键字插入到堆R中去,并保证插入R后仍是堆。

提示:应为堆R增加一个长度属性描述(即改写本章定义的SeqList类型描述,使其含有长度域);将key先插入R中已有元素的尾部(即原堆的长度加1的位置,插入后堆的长度加1),然后从下往上调整,使插入的关键字满足性质。

请分析算法的时间。

答:#define n 100//假设文件的最长可能长度typedef int KeyType; //定义KeyType 为int 型typedef struct node{KeyType key; //关键字域OtherInfoType info; //其它信息域,}Rectype; //记录结点类型typedef struct{Rectype data[n] ; //存放记录的空间int length;//文件长度}seqlist;void heapInsert(seqlist *R,KeyType key){//原有堆元素在R->data[1]~R->data[R->length],//将新的关键字key 插入到R->data[R->length+1]位置后,//以R->data[0]为辅助空间,调整为堆(此处设为大根堆)int large;//large 指向调整结点的左右孩子中关键字较大者int low,high;//low 和high 分别指向待调整堆的第一个和最后一个记录int i;R->length++;R->data[R->length].key=key;//插入新的记录for(i=R->length/2;i>0;i--)//建堆{low=i;high=R->length;课后答案网R->data[0].key=R->data[low].key;//R->data[low]是当前调整的结点for(large=2*low;large<=high;large*=2){//若large>high,则表示R->data[low]是叶子,调整结束;//否则令large 指向R->data[low]的左孩子if(large<high&&R->data[large].key<R->data[large+1].key)large++;//若R->data[low]的右孩子存在//且关键字大于左兄弟,则令large 指向它if (R->data[0].key<R->data[large].key){ R->data[low].key= R->data[large].key;low=large;//令low 指向新的调整结点}else break;//当前调整结点不小于其孩子结点的关键字,结束调整}//endforR->data[low].key=R->data[0].key;//将被调整结点放入最终的位置上}//end of for}end of heapinsert算法分析:设文件长度为n,则该算法需进行n/2 趟调整,总的时间复杂度与初建堆类似,最坏时间复杂度为O(nlgn),辅助空间为O(1).22.写一个建堆算法:从空堆开始,依次读入元素调用上题中堆插入算法将其插入堆中。

相关文档
最新文档