排序算法_案例

在这里插入图片描述

案例:
(1)设待排序的关键字序列为{12、2、16、30、28、10、16*、20、6、18},试分别写出使用以下排序方法,每趟排序结束后关键字序列的状态。

  1. 直接插入排序
    【算法思想】
    ①设待循环的记录存放在数组r[1…n]中,r[1]是一个有序序列。
    ②循环n-1次,每次使用顺序查找法,查找r[i](i=2、···、n)在已排好序的序列r[1···i-1]中的位置插入位置,然后将r[i]插入表长为i-1的有序序列r[1···i-1],直到将r[n]插入表长为n-1的有序序列r[1···n-1],最后得到一个表长为n的有序序列。
    ③直接插入排序算法是稳定排序算法;时间复杂度为O(n*n);空间复杂度为O(1)。

    序列初始序列为{12、2、16、30、28、10、16*、20、6、18}
    第一趟:{2、12、}16、30、28、10、16*、20、6、18
    第二趟:{2、12、16、}30、28、10、16*、20、6、18
    第三趟:{2、12、16、30、}28、10、16*、20、6、18
    第四趟:{2、12、16、28、30、}10、16*、20、6、18
    第五趟:{2、10、12、16、28、30、}16*、20、6、18
    第六趟:{2、10、12、16、16*、28、30、}20、6、18
    第七趟:{2、10、12、16、16*、20、28、30、}6、18
    第八趟:{2、6、10、12、16、16*、20、28、30、}18
    第九趟:{2、6、10、12、16、16*、18、20、28、30、}

  2. 折半插入排序
    【算法思想】
    ①设待循环的记录存放在数组r[1…n]中,r[1]是一个有序序列。
    ②循环n-1次,每次使用折半查找法(mid=(low+high)/2),查找r[i](i=2、···、n)在已排好序的序列r[1···i-1]中的位置插入位置,然后将r[i]插入表长为i-1的有序序列r[1···i-1],直到将r[n]插入表长为n-1的有序序列r[1···n-1],最后得到一个表长为n的有序序列。
    ③直接插入排序算法是稳定排序算法;时间复杂度为O(n*n);空间复杂度为O(1)。

    序列初始序列为{12、2、16、30、28、10、16*、20、6、18}
    第一趟:{2、12、}16、30、28、10、16*、20、6、18
    第二趟:{2、12、16、30、28、10、16*、20、6、18
    第三趟:{2、12、16、30、}28、10、16*、20、6、18
    第四趟:{2、12、16、28、30、}10、16*、20、6、18
    第五趟:{2、10、12、16、28、30、}16*、20、6、18
    第六趟:{2、10、12、16、16*、28、30、}20、6、18
    第七趟:{2、10、12、16、16*、20、28、30、}6、18
    第八趟:{2、6、10、12、16、16*、20、28、30、}18
    第九趟:{2、6、10、12、16、16*、18、20、28、30、}

  3. 希尔排序(增量选用5、3、1)
    【算法思想】
    希尔排序实质上是采用分组插入的方法。先将整个待排记录序列分割成几组,从而减少参与直接插入排序的数据量,对每组分别进行直接插入排序,然后增加每组的数据量,重新分组。
    这样当经过几次分组排序后,整个序列中的记录“基本有序”时,再对全体记录进行一次直接
    插入排序。
    希尔对记录的分组,不是简单地“逐段分割”,而是将相隔某个“增量”的记录分成
    一组
    ①第一趟取增量d1(d1<n)把全部记录分成d1个组,所有间隔为d1的记录分在同一组,在各个组中进行直接插入排序
    ②第二趟取增量d2(d2<d1),重复上述的分组和排序。
    ③依次类推,直到所取的增量d=1(d<d1<<d2<d1)所有记录在同一组中进行直接插入排序为止。

    序列初始序列为{12、2、16、30、28、10、16*、20、6、18}
    第一趟:{10、2、16、6、18、12、16*、20、30、28}(增量为5)
    第二趟:{6、2、12、10、18、16、16*、20、30、28}(增量为3)
    第三趟:{2、6、10、12、16、16*、18、20、28、30}(增量为1)

  4. 冒泡排序
    【算法思想】
    ① 设待排序的记录存放在数组r[1中。首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序(即r[1].keylr[2].key),则交换两个记录。然后比较第二个记录和第三个记录的关键字。依次类推,直至第n-1个记录和第n个记录的关键字进行过比较为止。上述过程称作第一趟起泡排序,其结果使得关键字最大的记录被安置到最后一个记录的位置上。
    ②然后进行第二趟起泡排序,对前n1个记录进行同样操作,其结果是使关键字次大的记录被安置到第n-1个记录的位置上。
    ③重复上述比较和交换过程,第i趟是从Lr[1]到Lr[ni+1]依次比较相邻两个记录的关键字,并在“逆序”时交换相邻记录,其结果是这n-i+1个记录中关键字最大的记录被交换到第n-i+1的位置上。直到在某一趟排序过程中没有进行过交换记录的操作,说明序列已全部达到排序要求,则完成排序。
    ④直接插入排序算法是稳定排序算法;时间复杂度为O(n*n);空间复杂度为O(1)

    序列初始序列为{12、2、16、30、28、10、16*、20、6、18}
    第一趟:{2、12、16、28、10、16*、20、6、18、[30]}
    第二趟:{2、12、16、10、16*、20、6、18、[28、30]}
    第三趟:{2、12、16、10、16*、6、18、[20、28、30]}
    第四趟:{2、10、12、16、6、16*、[18、20、28、30]}
    第五趟:{2、10、12、6、16、[16*、18、20、28、30]}
    第六趟:{2、10、6、12、[16、16*、18、20、28、30]}
    第七趟:{2、6、10、[12、16、16*、18、20、28、30]}
    第八趟:{2、6、10、12、16、16*、18、20、28、30}

  5. 快速排序
    【算法思想】
    在待排序的n个记录中任取一个记录(通常取第一个记录)作为枢轴(或支点)设其关键字为 pivotkey。经过一趟排序后,把所有关键字小于 pivotkey的记录交换到前面,把所有关键字大于 pivotkey的记录交换到后面,结果将待排序记录分成两个子表,最后将枢轴放置在分界处的位置。然后,分别对左、右子表重复上述过程,直至每一子表只有一个记录时,排序完成。
    其中,一趟快速排序的具体做法如下。
    (1)附设两个指针low和high,初始时分别指向表的下界和上界,设枢轴记录的关键字为 pivotkey(第一趟时,low=1;high=llength;)
    .(2)从表的最右侧位置,依次向左搜索找到第一个关键字小于 pivotkey的记录和枢轴记录交换。具体操作是:当low<high时,若hig所指记录的关键字大于 pivotkey,则向左移动指针high(执行操作–high);否则将hig所指记录与枢轴记录交换。
    (3)然后再从表的最左侧位置,依次向右搜索找到第一个关键字大于 pivotkey的记录和枢轴记录交换。具体操作是:当low<high时若low所指记录的关键字小于 pivotkey,则向右移动指针low(执行操作++low);否则将low所指记录与枢轴记录交换。
    (4)重复步骤(2)和(3),直至low与high相等为止。此时low或high的位置即为轴在此趟排序中的最终位置,原表被分成两个子表。
    在上述过程中,记录的交换都是与枢轴之间发生,每次交换都要移动3次记录,可以先将枢轴记录暂存在r[0]的位置上,排序过程中只移动要与枢轴交换的记录,即只做r[low]或
    r[high]的单向移动,直至一趟排序结束后再将枢轴记录移至正确位置上。

    序列初始序列为{12、2、16、30、28、10、16*、20、6、18}
    第一趟:{6、2、10、12、28、30、16*、20、16、18} pivot=12
    第二趟:{2、6、10、12、28、30、16*、20、16、18} pivot=6
    第三趟:{2、6、10、12、18、16、16*、20、28、30} pivot=28
    第四趟:{2、6、10、12、16*、16、18、20、28、30} pivot=18
    第五趟:{2、6、10、12、16、16*、18、20、28、30}

  6. 简单选择排序
    【算法思想】
    ①设待排序的记录存放在数组r[1…n]中。第一趟从r[1]开始,通过1-1次比较,从n个记录中选出关键字最小的记录,记为t内,交换f1]和t因。
    ②第二趟从[2]开始,通过n-2次比较,从n-1个记录中选出关键字最小的记录,记为tk,交换r2]和r因。
    ③依次类推,第i趟从t[开始,通过n-i次比较,从-++1个记录中选出关键字最小的记录,记为t因,交换t[和r因。
    ④经过m-1趟,排序完成。

    序列初始序列为{12、2、16、30、28、10、16*、20、6、18}
    第一趟:{[2、]12、16、30、28、10、16*、20、6、18}
    第二趟:{[2、6、]12、16、30、28、10、16*、20、18}
    第三趟:{[2、6、10、]12、16、30、28、16*、20、18}
    第四趟:{[2、6、10、12、]16、30、28、16*、20、18}
    第五趟:{[2、6、10、12、16、]30、28、16*、20、18}
    第六趟:{[2、6、10、12、16、16*、]30、28、20、18}
    第七趟:{[2、6、10、12、16、16*、18、]30、28、20}
    第八趟:{[2、6、10、12、16、16*、18、20、]30、28}
    第九趟:{2、6、10、12、16、16*、18、20、28、30、}

  7. 二路并归排序
    【算法思想】
    二路归并排序将R[low…high]中的记录归并排序后放入T[low…high]中当序列长度等于1时,递归结束,否则:
    ①将当前序列一分为二,求出分裂点mid=[(low+high)/2]
    ②对子序列R[low…mid]递归,进行归并排序结果放入S[low…mid]中
    ③对子序列R[mid+1…high]递归,进行归并排序,结果放入S[mid+1…high]中
    ④调用算法Merge,将有序的两个子序列S[low…mid]和S[mid+1…high]归为一个有序的序列T[low…high]

    序列初始序列为{12、2、16、30、28、10、16*、20、6、18}
    第一趟:{[2、12、] [16、30、] [10、28、] [16*、20、] [6、18]}
    第二趟:{[2、12、16、30、] [10、16*、20、28、] [6、18]}
    第三趟:{[2、10、12、16、16*、20、28、30、] [6、18]}
    第四趟:{2、6、10、12、16、16*、18、20、28、30}

(2)给出如下关键字序列{321、156、57、46、28、7、331、33、34、63},试按链式基数排序方法,列出每一趟分配和收集的过程。
【算法思想】
第一趟分配对最低数位关键字(个位数)进行,改变记录的指针值将链表中的记录分配至10个链队列中去,每个队列中的记录关键字的个位数相等,一趟收集是改变所有非空队列的队尾记录的指针域,令其指向下一个非空队列的队头记录,重新将10个队列中的记录链成一个链表。
第二趟分配和第二趟收集是对十位数进行的,其过程和个位数相同。
第三趟分配和第三趟收集是对百位数进行的,过程同上。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值