排序 Sorting.

Slides:



Advertisements
Similar presentations
第 8 章 数组 计算机科学学院 李淮 Tel QQ
Advertisements

While 迴圈 - 不知重複執行次數
“八皇后”问题 崔萌萌 吕金华.
第5章 排序与查找 PART A 《可视化计算》.
第九章 排序 插入排序 交换排序 选择排序 归并排序 基数排序.
第十章 内部排序 10.1 概述 10.2 插入排序 直接插入排序 其他插入排序 希尔排序
C语言基础——指针的高级应用 Week 05.
第8章 字串與陣列 8-1 字串處理 8-2 一維陣列的處理 8-3 建立多維陣列 8-4 不規則陣列與參數傳遞 8-5 陣列排序與搜尋.
Tree(樹) 什麼是「樹」? 「樹」的範例 「樹」的定義 「樹」的表示法.
課程名稱:資料結構 授課老師:_____________
C语言程序设计 课程 第5章 数组 主讲:李祥 博士、副教授 单位:软件学院软件工程系.
高级语言程序设计 主讲人:陈玉华.
主讲人: 吕敏 { } Spring 2012 ,USTC 算法基础 主讲人: 吕敏 { } Spring 2012 ,USTC.
循环结构又称为重复结构:用来处理需要重复处理的问题,它是程序中一种很重要的结构。
選擇排序法 通訊一甲 B 楊穎穆.
佇列 (Queue).
第8章 排序.
第十章 排序.
第九章 排序 概述 插入排序 交换排序 选择排序 归并排序 基数排序 外排序.
第九章 排序 9.1排序的基本概念 9.2简单排序方法(复杂度 O(n2)) 9.3先进排序方法(复杂度 O(nLogn))
快速排序法 (Quick Sort).
第9章 排序.
第十章 排序與搜尋.
1、基本概念 2、插入排序 3、交换排序 4、选择排序 5、归并排序 6、基数排序 7、外部排序
If … else 選擇結構 P27.
搜尋資料結構 Search Structures.
程式撰寫流程.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第8章 排 序 8.1 排序技术概述 8.2 插入排序 8.3 选择排序 8.4 交换排序 8.5 归并排序 8.6 基数排序
Introduction to the C Programming Language
第四章 C 语言中的输入和输出.
C语言 程序设计基础与试验 刘新国、2012年秋.
中央广播电视大学开放教育试点课程 数据结构 辅导教师 倪政林.
Sorting 排序 Bubble Sort O(n2) Insert Sort Selection Sort Quick Sort
数据结构 Data Structure CSU 主讲人:王国军,郑瑾 中南大学信息院计科系
第八章 使用指针.
第十章 指针.
如何赢一个机械键盘
第5讲 结构化程序设计(Part II) 周水庚 2018年10月11日.
第0章作业: 教材P12-练习与实践 1.写出用符号’*’输出描绘汉字”大”的流程图。
教 师:曾晓东 电 话: E_mail: 计算机软件技术基础 教 师:曾晓东 电 话: E_mail:
C语言概述 第一章.
資料結構與C++程式設計進階 排序與搜尋 講師:林業峻 CSIE, NTU 6/ 14, 2010.
程式結構&語法.
第8章 資料排序 資料結構設計與C++程式應用
資料結構與演算法 第一章 基本概念 徐熊健 資料結構與演算法 徐熊健.
第九章 排序 概述 插入排序 快速排序 交换排序(起泡排序) 选择排序 归并排序.
Main() { Dfas Asdfasf fasdfa } #include <stdio.h> void main( ) {
第1章 绪论(二) 教学目标 理解算法的特性及评价标准 掌握算法时间复杂度和空间复杂度的分析方法 1/
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
99高中資訊科選修課程 夥伴學習教師 專業進修研習 進階程式設計--演算法 教學示例與研討
第十四章 若干深入问题和C独有的特性 作业: 函数指针 函数作参数 函数副作用 运算 语句 位段 存储类别 编译预处理
第十章 优化 网上教学系统: : 编译原理 第十章 优化 网上教学系统: : 编译原理.
算法导论第一次习题课.
資料結構與C++程式設計進階 遞迴(Recursion) 講師:林業峻 CSIE, NTU 6/ 17, 2010.
陣列 東海大學物理系‧資訊教育 施奇廷.
累堆排序法 (Heap Sort).
单片机原理及应用 实践部分 主讲人:刘 强 四川工商学院单片机教学团队 单片机原理及应用 实践部分 主讲人:刘 强
第四章 C 语言中的输入和输出.
第七章  数 组.
程式設計--linear search 通訊一甲 B 楊穎穆.
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
本教學投影片係屬教科書著作之延伸,亦受著作權法之保護。
Chap 7 数 组 7.1 排序问题 7.2 找出矩阵中最大值所在的位置 7.3 进制转换.
資料結構 老師:李崇明 助教:楊斯竣.
C/C++基礎程式設計班 陣列 講師:林業峻 CSIE, NTU 3/14, 2015.
算法的基本思想: 第6章 内部排序 6.2 气泡排序 将待排序的记录看作是竖着排列的“气泡”,关键字较小 的记录比较轻,从而要往上浮。
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
排序 排序(sorting)是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列。 由于待排序的记录数量不同,使得排序过程中涉及的存储器不同,可将排序方法分为两大类:一类是内部排序,指的是待排序记录存放在计算机存储器中进行的排序过程;另一类是外部排序,指的是待排序记录的数量很大,以致内存一次不能容纳全部记录,在排序过程中对外存进行访问的排序过程。
Q1(a) 小偉打算編寫一個程序。該程序把兩個44的表內的數字相加。表3內的數字是由表1和表2應格子內的數字相加而成。例如:
Presentation transcript:

排序 Sorting

學習目標 在學習本章之後,讀者們要能夠瞭解: 排序的定義及種類。 各種排序資料結構演算法。 各種排序的比較。

 簡介 排序(Sorting)是指一群資料按照某一個排列規則,重新安排此群資料的次序,使其相對於此規則具有一種遞增(或遞減)性質的線性次序關係。 排序可分成下列兩大類: 內部排序(Internal Sorting):意指資料量小,可以直接放在記憶體內進行。 外部排序(External Sorting):意指資料量大,無法直接存放在記憶體,必須先存放於輔助記憶體內再處理。

其中內部排序的方法常見的有: 插入排序法(Insertion Sort) 選擇排序法(Selection Sort) 氣泡排序法(Bubble Sort) 謝耳排序法(Shell Sort) 快速排序法(Quick Sort) 合併排序法(Merge Sort) 累堆排序法(Heap Sort) 基數排序法(Radix Sort)

若按演算法的時間複雜度,以及鍵值的比較方式,又可將這些內部排序區分為下面三種模式: 簡單排序技巧: 選擇排序、插入排序、謝耳排序及氣泡排序。 謝耳的平均時間複雜度為O(n(logn)2)及最差時間複雜度為O(Ns),1<s<2 選擇排序、插入排序及氣泡排序平均時間複雜度及最差時間複雜度均為O(n2)。

高等排序技巧: 使用的方法是每次比較兩個鍵值後,便分成兩個部份,而選擇其中一部份先處理,即決策樹(Decision Tree)型式。 有快速排序、合併排序、累堆排序 除了快速排序最差時間複雜度為O(n2),其他的平均時間複雜度及最差時間複雜度均為O(nlogn)。 基數排序技巧: 屬於分配性排序之一,此方法的平均時間複雜度為O(nlogpk), 最差時間複雜度則為O(nlogpk)~ O(n) 其中p為所使用基底(Base,Radix),k為數值的位數。

插入排序法 (Insertion Sort)

定義 插入排序法的基本運算是將一個元素插入一串已排序的元素之中,使該串元素仍然按順序排列。 掃瞄已排序好的串列 若找到元素小於這個欲插入的元素,將元素向下移動以空出一個位置。 當掃瞄到某一元素大於欲插入值,則掃瞄停止,較大之元素之後剛好有一空位可被插入。

基本運算 index 1 2 3 4 5 i 60 70 15 40 80 99 說明 60不變 70插入陣列中index為0的位置 1 2 3 4 5 i 60 70 15 40 80 99 說明 60不變 70插入陣列中index為0的位置 15不變 40插入陣列中index為2的位置 80插入陣列中index為0的位置 99插入陣列中index為0的位置

演算法 =>虛擬程式碼 演算法則如下: procedure insertionsort(int data[ ], int n) { index i, j ; int item ; for (i 從1~ n-1) { 每次將data[i]中的元素當成欲加入的元素; 從已排序完的陣列的最後 { 從前尋找可以加入的地方; 將所有元素往後位移一格;    } } }

=>C語言程式碼 insertionsrot(int data[ ], int n) { index i, j ,item; for (i=1; i<n; i++) /*共n+1次*/ { item=data[i]; j=i; /*當data[i]小於前面排好的資料時,將較大的資料 往後移*/ while (j>0 && a[j-1]>item) { data[j]=data[j-1]; j- -; data[j] = item; /*將a[i]插入適當位置*/ } } }

=>時間複雜度分析 插入排序是相當穩定的 最壞時間和平均時間複雜度皆為O(n2) 所需的額外空間很少。

程式範例-插入排序 # include <studio.h> void insertion_sort ( int [ ], int ) ; void main ( ) { int data [20] ; int size = 0, i; printf ( “\nPlease enter number to sort (enter 0 when end):\n ) ; printf ( “Number : “ )

do { scanf ( “%d “, &data [size] ); } while (data [size ++] != 0 ) ; for ( i = 0; i < 60 ; i ++ ) printf ( “-” ) ; printf ( “\nSorting : “ ); for ( I = 0; I < size ; i ++) printf ( “%d “, data [i] ); }

void insertion_sort (int data[ ], int size ) { int base, compare, temp, i; for (base = 1; base < size ; base ++) temp = data [base] ; compare = base ; while ( compare > 0 && data [compare – 1] > temp)

{ data [compare] = data [compare – 1]; compare - -; } data [compare] = temp ; printf ( “Access : “) ; for ( I = 0; i < size ; i ++) printf ( “%d “, data [i]) ; printf ( “\n” ) ;

氣泡排序法 (Bubble Sort)

定義 氣泡排序可說是最簡單的排序法之一 屬於交換排序(Swap sort)的方法 一開始資料都都放在同一個陣列中,比較相鄰的陣列元素大小,依照排序來決定是否交換彼此的值,這樣的比較從輸入陣列的第一個元素開始,跟相鄰元素比大小。

基本運算 泡沫排序的基本運算是將一對相鄰的元素互換。 整個排序過程由許多回合構成,每一回合由陣列的一端開始,向另一端執行互換。每對元素若其順序相反時,則兩者互換

index 1 2 3 4 5 i 60 70 15 40 80 99 (a) 原始資料 (b) 第一次排序 (c) (d) (e) (f) 第二次排序 第三次排序 第四次排序 第五次排序(結束)

演算法 =>虛擬程式碼 Bubble_sort(int a[ ], int size) { for (pass = size-1 to 1) for ( j = 1 to size – 1) if (a[ j ]>a[ j+1 ] 交換a[ j ] , a[ j+1 ] }

=>C語言程式碼 Bubble_sort(int a[ ], int size) { int i , j , t; for (i = size-1; i>0 ; i- -) for ( j = 0; j<1; j + +) if (a[ j ]>a[ j+1 ] t=a[ j ]; a[ j ]=a[ j+1 ]; a[ j+1 ]=t; }

=>時間複雜度分析 氣泡排序是相當穩定的 最壞時間和平均時間複雜度皆為O(n2), 所需的額外空間很少。

程式範例 #include <stdio.h> #define n 10 // 定義陣列大小 void bubble(int *);       // 氣泡排序副程式 void show(int *);         // 列印陣列 void main() { int data[n] = {9,1,7,3,4,8,6,2,5,0}; printf("The default is :"); show(data);              // 印出預設陣列 bubble(data);            // 執行氣泡排序法 printf("The answer is :"); show(data);              // 印出答案 }

void bubble(int *data) { int temp,i,j,flag; for (i=n-1;i>=0;i--)                // 變數i遞減 flag = 0;                // 設定交換次數為0次 for (j=0;j< i;j++) if(data[j] > data[j+1])           // 當data[j] > data[j+1]執行交換 printf("\ndata[%d] > data[%d]",j ,j+1); printf(" data[%d],data[%d] swap,",j ,j+1); temp = data[j+1]; data[j+1] = data[j]; data[j] = temp; flag++;  // 如果有交換過執行flag++; }

else                           // 當data[j] <= data[j+1]不交換 { printf("\ndata[%d] <=data[%d]",j ,j+1); printf(" data[%d],data[%d] not swap",j,j+1); } if(flag==0)                //flag為0表示沒有交換過,現在的陣列即為所求 break;

printf("\nThe %d time is :",-(i-n));      // 印出回合次數 show(data);                    // 印出執行此回合後陣列情況 printf("\n"); } void show(int *data) { int i; for(i=0;i< n;i++) printf("%d,",*(data+i));

選擇排序法 (Selection Sort)

定義 選擇排序從輸入的陣列中選擇最大(或最小)的值,移到輸出陣列中,原來儲存最大(或最小)值的陣列元素則以0代之,這樣的操作一直進行到所有陣列元素都被輸出為止。

原選擇排序

選擇排序使用了兩個陣列,假如把選擇排序和交換排序的技巧合在一起,只要使用一個陣列,由於每一輪都有一個元素就定位,下一輪要處理的元素數目就少一個,因此,改良以後的排序方法執行的效率也比較好。

改良後的選擇排序

基本運算 選擇排序法(selection sort)的基本運算是由一連串的元素中選出一個最小元素(或是最大元素)。

index 1 2 3 4 5 i 60 70 15 40 99 80 原始資料 第一次排序 第二次排序 第三次排序 第四次排序 第五次排序(結束)

演算法 =>虛擬程式碼 select_sort (int a[ ], int size) { index i , j ; for (i = n –1到1) 最大值 = data [0] ; for ( j = 1 到 i) if ( a[ j ]>最大值 ) 最大值 = a [ j ] ; } 將a [ j ]與 a [ i ]的資料互換 ;

=>C語言程式碼 select_sort(int a[ ], int size) { int i, j , index, larger; //在1~i的數中,將最大的數放到a [i ]中// for (i = n-1 ; I>0 ; i--) larger= a[0]; index =0; for (j=1; j<=i; j + +)

if(a[j]>larger) { larger = a[j]; index = ; } a[index] = a[i]; a[i] = larger;

=>時間複雜度分析 外層迴路需執行n-1次,內層共n-i次, 每次需執行一個比較運算及可能的指定運算。執行時間為: 此法無論資料原始排列方式如何,總需 O(n2 )的比較運算。 其資料移動次數最多是O(n)次。

選擇排序程式範例 #include <stdio.h> #define n 10 void selection(int *);            // 傳入陣列作選擇排序 void show(int *);                 // 列印陣列 void main() { int data[n] = {9,1,7,3,4,8,6,2,5,0}; printf("The default is :"); show(data); selection(data); printf("The answer is :"); }

void selection(int *data) { int temp,i,j,flag; for (i=0;i< n;i++) for (j=i;j< n;j++) if(data[i] > data[j])         // 當data[i] > data[j]時交換 printf("\ndata[%d] > data[%d]",i ,j); printf(" data[%d],data[%d] swap,",i ,j); temp = data[j]; data[j] = data[i]; data[i] = temp; } // 當data[i] <= data[j]時不交換

else { printf("\ndata[%d] <=data[%d]",i ,j); printf(" data[%d],data[%d] not swap",i ,j); } printf("\nThe %d time is :",i+1); show(data); printf("\n");

void show(int *data) { int i; for(i=0;i< n;i++) printf("%d,",*(data+i)); }

快速排序法 (Quick Sort)

定義 由C. A. R. Hoare 所創的快速排序法。 其主要的原理是利用遞迴概念,將陣列分成二部份: 第一部分中的所有元素的值都小於某一個預先選定的基準值(pivot), 第二部分中的所有元素的值都大於基準值; 這二部分的資料再根據同樣的方式,再分別作快速排序。

基本運算 假設要排序的元素如下: K(1),K(2),……,K(n) 則快速排序法的一個步驟是將串列分割成兩個子串列

其演算的步驟: 若n=1,則return; 令分隔點K(p)為第一筆資料的值 由左向右找出一筆資料K(i),使得K(i)>K(p); 由右向左找出一筆資料K(j),使得K(j)<K(p); 若i<j則K(i)與K(j)交換,並回到步驟2; 若i≧j,則將K(j)與K(p)交換,並以j為基點將資料分割成左右兩半,然後分別針對左右兩半進行步驟1~5。

演算法 =>C語言程式碼 quick_sort(int a[ ], int l, int r) { int p, i, j, t ; if ( l < r) i = l +1 j = r ; p = a [ l ];

do { while (a [ i ] < p) i + +; while (a [ j ] > p) j - - ; if ( i < j ) { t = a [ i ]; a [ i ] = a [ j ] ; a [ j ] = t; }

while ( i < j ); a [ l ] = a [ j ]; a [ j ] = p ; qsort ( a, l, j – 1) ; qsort ( a, j + 1, r ) ; }

=>時間複雜度分析 最差情況: 若所選的pivot每次皆最小值,則執行時間

平均分析 假設所選的pivot將串列分成兩個子串列,其平均執行時間分別 為T(j),和T(n-j-1),j之值可能由1到n且機率皆相等,因此 T(n) = O(nlogn)

程式實例 #include <studio.h> void quick_sort ( int [ ], int ) ; void main ( ) { int data [20] ; int size = 0, i; printf ( “\nPlease enter number to sort (enter 0 when end):\n ) ; printf ( “Number : “ ) do { scanf ( “%d “, &data [size] ); } while (data [size ++] != 0 ) ; for ( i = 0; i < 60 ; i ++ ) printf ( “-” ) ; printf ( “\nSorting : “ ); for ( I = 0; I < size ; i ++) printf ( “%d “, data [i] ); }

void quick_sort (int data[ ], int left, int right, int size ) { int lbase, rbase, compare, temp, i; for (base = 1; base < size ; base ++) temp = data [base] ; compare = base ; while ( compare > 0 && data [compare – 1] > temp) data [compare] = data [compare – 1]; compare - -; } data [compare] = temp ; printf ( “Access : “) ; for ( I = 0; i < size ; i ++) printf ( “%d “, data [i]) ; printf ( “\n” ) ;