資料結構與演算法之二 排序
阿新 • • 發佈:2019-01-05
視訊解析 https://edu.csdn.net/course/play/7813
假定,你要為你的生日聚會邀請你的朋友和親戚。對此,你需要給他們打電話。你正在擁有10,000條記錄的電話本中查詢名為Steve的電話號碼。然而,電話本中的記錄是以隨意順序儲存的。要在這樣一個目錄中查詢你朋友的電話號碼,你需要按順序在目錄中瀏覽每個條目。這將非常耗時,你如何解決此問題呢?
或降序。
如果資料被排序,則可以直接轉到儲存以
‘
S
’
開頭的姓名部分,因此減少了要
遍歷的記錄數。
執行時間
儲存空間
程式設計工作
重複步驟
3
區分
0
到
n
–
1
通道中的
j
。
1.
如果索引
j
處的元素大於索引
j + 1
處的元素,則交換這兩個元素。
3.
按
1
遞增通道
;
圈數加
1
4.
如果通道
<= n-1
,則轉到第
2
步
。
當實現氣泡排序演算法時,在通道1中將執行多少次比較? 答案: n –1次比較
使用選擇排序來排序資料
選擇排序演算法: 選擇排序還具有二次方程增長階,且因此僅適用於排序小的列表。 選擇排序通過列表反覆掃描,每次掃描選擇一項,然後將這一項移動到列表中 正確的位置。
要理解選擇排序演算法的實現,考慮陣列中儲存的未排序的數字列表。每次都尋找最小值,將最小值往前放
編寫一演算法以實現選擇排序。 選擇排序的演算法: 1. 重複步驟 2 和 3 區分 0 到 n -2 通道中的 j 2. 找出 arr[j] 到 arr[n – 1] 中的最小值 : a. 設定 min_index = j b. 重複步驟 c 區分 j + 1 到 n – 1 的 i c. 如果 arr[i] < arr[min_index]: i. min_index = i 3. 將 arr[j] 與 arr[min_index] 交換
在選擇排序中, 在查詢最小元素的通道 1 中有 n – 1 次比較。 在查詢第二個最 小元素的通道 2 中有 n -2 次比較,依此類推。 比較總數 = (n – 1) + (n – 2) + (n – 3) + … + 3 + 2 + 1 = n(n – 1)/2 n(n – 1)/2 是 O(n2) 階的級數。 因此,選擇排序演算法是階 O(n2) 的演算法。
插入排序演算法: 具有二次方程增長階,且因此僅用於排序小列表。 如果需要排序的列表幾乎已經排序,則插入排序比氣泡排序和選擇排序更有效率。
要理解插入排序演算法的實現,考慮陣列中儲存的未排序的數字列表。
若要通過使用插入排序排序大小為n的列表,您需要執行(n– 1) 次通道。 最佳用例效率: 當列表已經被排序時產生最佳用例。 在這種情況下,您必須在每個通道中僅做一次比較。 在n– 1次通道中,您將需要做n– 1次比較。 插入排序的最佳用例效率是O(n)階的。 最糟用例效率: 當列表按反向順序排序時產生最糟用例效率。 在這種情況下,您需要在第1個通道中做1次比較,在第二個通道中做2次比較,在第3個通道中做3次比較,在第n– 1 個通道中做n – 1次比較。 插入排序的最糟用例效率是O(n2)階的。
在本章中,你已經學到: 排序是按照某些預定義的順序或關鍵值排列資料的過程。 此順序可以是升序或 降序。 用於排序資料有各種排序演算法。 其中一些如下: 冒 泡排序 選擇排序 插入排序 殼排序 合併排序 快速排序 堆排序
若要選擇合適的演算法,您需要考慮以下內容: 執行時間 儲存空間 程式設計工作 氣泡排序和選擇排序演算法具有二次方程增長階,且因此僅適用於排序小的列表。 插入排序執行不同次數的比較,這取決於最初的元素分階。 當元素已經處於排 序階,則插入排序需要進行極少比較。 如果需要排序的列表幾乎已經排序,則插入排序比氣泡排序和選擇排序更有效率。
通過比較按若干位置的距離分隔的元素,殼排序改善了插入排序 。 這幫助元素快 速靠近正確的位置,因此減少了比較的次數。
--------------------------
---------------------
節省時間和高效搜尋資料的簡單解決方案是排序。 排序 是按照某些預定義的順序或序列排列資料的過程。 此順序可以是升序
選擇排序演算法
通過使用一演算法實現在程式中排序。 一些排序演算法有: 冒泡 ( Bubble ) 排序 選擇排序 插入排序 殼( Shell )排序 合併排序 快速排序 堆排序 要選擇合適的演算法,你需要考慮以下方面:
氣泡排序演算法: 是最簡單的排序演算法之一 此演算法具有二次方程增長階,因此適合僅排序小列表 通過列表重複掃描、比較相鄰元素和按錯誤順序交換,此演算法會有作用 .
編寫一演算法以實現 冒 泡排序。 冒 泡排序的演算法是: 1. 設定通道 ( 圈數 ) = 1 。 2.
排序演算法的效率按照比較次數來測量。 在 冒 泡排序中,通道 1 內有 n – 1 次比較,通道 2 中有 n – 2 次比較,依此類推。 比較總數 = (n – 1) + (n – 2) + (n – 3) + … + 3 + 2 + 1 = n(n – 1)/2 。 n(n – 1)/2 是 O(n2) 階的級數。 因此, 冒 泡排序演算法是階 O(n2) 的演算法。
什麼是氣泡排序演算法的增長階? 答案: n – 1 次比較
答案: 氣泡排序演算法具有二次方增長階
當實現氣泡排序演算法時,在通道1中將執行多少次比較? 答案: n –1次比較
使用選擇排序來排序資料
選擇排序演算法: 選擇排序還具有二次方程增長階,且因此僅適用於排序小的列表。 選擇排序通過列表反覆掃描,每次掃描選擇一項,然後將這一項移動到列表中 正確的位置。
要理解選擇排序演算法的實現,考慮陣列中儲存的未排序的數字列表。每次都尋找最小值,將最小值往前放
編寫一演算法以實現選擇排序。 選擇排序的演算法: 1. 重複步驟 2 和 3 區分 0 到 n -2 通道中的 j 2. 找出 arr[j] 到 arr[n – 1] 中的最小值 : a. 設定 min_index = j b. 重複步驟 c 區分 j + 1 到 n – 1 的 i c. 如果 arr[i] < arr[min_index]: i. min_index = i 3. 將 arr[j] 與 arr[min_index] 交換
在選擇排序中, 在查詢最小元素的通道 1 中有 n – 1 次比較。 在查詢第二個最 小元素的通道 2 中有 n -2 次比較,依此類推。 比較總數 = (n – 1) + (n – 2) + (n – 3) + … + 3 + 2 + 1 = n(n – 1)/2 n(n – 1)/2 是 O(n2) 階的級數。 因此,選擇排序演算法是階 O(n2) 的演算法。
插入排序演算法: 具有二次方程增長階,且因此僅用於排序小列表。 如果需要排序的列表幾乎已經排序,則插入排序比氣泡排序和選擇排序更有效率。
要理解插入排序演算法的實現,考慮陣列中儲存的未排序的數字列表。
若要通過使用插入排序排序大小為n的列表,您需要執行(n– 1) 次通道。 最佳用例效率: 當列表已經被排序時產生最佳用例。 在這種情況下,您必須在每個通道中僅做一次比較。 在n– 1次通道中,您將需要做n– 1次比較。 插入排序的最佳用例效率是O(n)階的。 最糟用例效率: 當列表按反向順序排序時產生最糟用例效率。 在這種情況下,您需要在第1個通道中做1次比較,在第二個通道中做2次比較,在第3個通道中做3次比較,在第n– 1 個通道中做n – 1次比較。 插入排序的最糟用例效率是O(n2)階的。
在本章中,你已經學到: 排序是按照某些預定義的順序或關鍵值排列資料的過程。 此順序可以是升序或 降序。 用於排序資料有各種排序演算法。 其中一些如下: 冒 泡排序 選擇排序 插入排序 殼排序 合併排序 快速排序 堆排序
若要選擇合適的演算法,您需要考慮以下內容: 執行時間 儲存空間 程式設計工作 氣泡排序和選擇排序演算法具有二次方程增長階,且因此僅適用於排序小的列表。 插入排序執行不同次數的比較,這取決於最初的元素分階。 當元素已經處於排 序階,則插入排序需要進行極少比較。 如果需要排序的列表幾乎已經排序,則插入排序比氣泡排序和選擇排序更有效率。
通過比較按若干位置的距離分隔的元素,殼排序改善了插入排序 。 這幫助元素快 速靠近正確的位置,因此減少了比較的次數。
/**********************************************************/
/*描述:編寫程式將10個學生的得分儲存到陣列中。通過使用氣泡排序演算法,來排序陣列中的元素,排序陣列後,顯示排序後陣列的元素*/
using System;
class List
{
//定義長度為20的整型陣列
private int[]a=new int[20]; //20是最大長度.
//陣列的個數
private int n;
//定義一個方法讀取資料元素到陣列
public void read()
{
//獲得
while(true)
{
Console.WriteLine("請輸入陣列元素的個數<20之內>:");
string s=Console.ReadLine();
n=Int32.Parse(s);//轉換為整型.Convert.ToInt32(s)
if(n<=20)
break; //跳出迴圈
else
Console.WriteLine("\n陣列只能夠容納20個數組元素.\n");
}//while結束.
Console.WriteLine("");
Console.WriteLine("----------------------------------");
Console.WriteLine("-----請輸入陣列元素---------------");
Console.WriteLine("----------------------------------");
//使用者將數句元素輸入陣列
for(int i=0;i<n;i++)
{
Console.Write("<"+(i+1)+">");
string s1=Console.ReadLine();
a[i]=Int32.Parse(s1);
}//<1>20 <2>20 <3>90
}
//*************************顯示陣列元素*************************
public void display()
{
Console.WriteLine("");
Console.WriteLine("-------------------------------------------");
Console.WriteLine("------------排序過後的元素-----------------");
Console.WriteLine("-------------------------------------------");
for(int j=0;j<n;j++)
{
Console.WriteLine(a[j]);
}
}
/***************氣泡排序方法***************************/
public void BubbleSortArray()
{
//圈數1--->n-1
for(int i=1;i<=n-1;i++) //i:1;不是陣列下標,是通道次數
{
//裡面做的工作是兩個相鄰數字的比較;如果不符合升序排列,則交換.j指陣列下標.
for(int j=0;j<n-i;j++) //注意:比較n-i次
{
if(a[j]>a[j+1]) //則說明不符合升序排列,需要交換
{
int temp;
temp =a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}//內層交換結束
}//圈數迴圈結束.
}
/******************Main()方法*********************/
public static void Main(string[]args)
{
List myList=new List();
myList.read(); //讀取資料元素
myList.BubbleSortArray(); //呼叫氣泡排序演算法
myList.display(); //顯示陣列元素
Console.WriteLine("\n\n按任意鍵退出.");
Console.Read();
}
}
--------------------------
/*
描述:使用選擇排序,來排列包含10個學生得分的整數陣列,升序排列.
*/
using System;
class Selection
{
//定義陣列的大小
private int[]a=new int[20];
//陣列元素的個數.
private int n;
//定義接受陣列元素的函式
void read()
{
while(true)
{
Console.WriteLine("請輸入陣列元素的個數:");
string s=Console.ReadLine();
n=Int32.Parse(s);
if(n<=20)
break;
else
Console.WriteLine("\n陣列只能夠接收20個元素.\n");
}
Console.WriteLine("");
Console.WriteLine("---------------------------------");
Console.WriteLine("----------請輸入陣列元素---------");
Console.WriteLine("---------------------------------");
//使用者輸入資料
for(int i=0;i<n;i++)
{
Console.Write("<"+(i+1)+">");
string s1=Console.ReadLine();
a[i]=Int32.Parse(s1);
}
}
//顯示陣列內容的函式
void display()
{
Console.WriteLine("");
Console.WriteLine("---------------------------------");
Console.WriteLine("----------排序後的陣列元素-------");
Console.WriteLine("---------------------------------");
for(int j=0;j<n;j++)
{
Console.WriteLine(a[j]);
}
}
/*
選擇排序演算法:每次選擇最小值,將其依次往前排;藉助於下標標記來實現.
*/
public void SelectionSortArray()
{
//外面進行了n-1圈
for(int i=0;i<n-1;i++)
{
//定義個指示最小值標記的變數
int min_index=i;
//查詢選擇最小值所對應的標記(下標)
for(int j=i+1;j<=n-1;j++)
{
//判斷如果有值比,最小值下標對應的數還小,則將該值對應的下標給min_index
if(a[j]<a[min_index])
min_index=j;
}//結束尋找最小值下標
//交換:a[i]<-->a[min_index]
swap(i,min_index); //呼叫交換方法.
}
}
//交換兩個值的方法
public void swap(int x,int y)
{
int temp;
temp=a[x];
a[x]=a[y];
a[y]=temp;
}
//類的主方法
public static void Main()
{
Selection sec=new Selection();
sec.read();
sec.SelectionSortArray();
sec.display();
Console.WriteLine("\n\n請按任意鍵結束!.");
Console.Read();
}
}
---------------------
/*
描述:使用插入排序,來排列包含10個學生得分的整數陣列。
*/
using System;
class Insertion
{
//定義陣列的大小
private int[]a=new int[20];
//陣列元素的個數.
private int n;
//定義接受陣列元素的函式
void read()
{
while(true)
{
Console.WriteLine("請輸入陣列元素的個數:");
string s=Console.ReadLine();
n=Int32.Parse(s);
if(n<=20)
break;
else
Console.WriteLine("\n陣列只能夠接收20個元素.\n");
}
Console.WriteLine("");
Console.WriteLine("---------------------------------");
Console.WriteLine("----------請輸入陣列元素---------");
Console.WriteLine("---------------------------------");
//使用者輸入資料
for(int i=0;i<n;i++)
{
Console.Write("<"+(i+1)+">");
string s1=Console.ReadLine();
a[i]=Int32.Parse(s1);
}
}
//顯示陣列內容的函式
void display()
{
Console.WriteLine("");
Console.WriteLine("---------------------------------");
Console.WriteLine("----------排序後的陣列元素-------");
Console.WriteLine("---------------------------------");
for(int j=0;j<n;j++)
{
Console.WriteLine(a[j]);
}
}
//****使用插入排序的方法
public void InsertionSortArray()
{
//重複n-1次來將為排序列表資料放入已排序列表
for(int i=1;i<n;i++)
{
int temp=a[i];
int j=i-1;
//如果j>=0或大於臨時值,則執行如下操作
while((j>=0)&&(a[j]>temp))
{
a[j+1]=a[j];
j--;
}
a[j+1]=temp;
}
}
//交換兩個值的方法
public void swap(int x,int y)
{
int temp;
temp=a[x];
a[x]=a[y];
a[y]=temp;
}
//類的主方法
public static void Main()
{
Insertion sec=new Insertion();
sec.read();
sec.InsertionSortArray();
sec.display();
Console.WriteLine("\n\n請按任意鍵結束!.");
Console.Read();
}
}
------------------------------------------------------------------------
/*
描述:使用插入排序,來排列包含10個學生得分的整數陣列。
*/
using System;
class ShellSorter
{
//陣列元素的個數.
private static int n=0;
//定義陣列的大小
private int[]a;
//定義接受陣列元素的函式
void read()
{
while(true)
{
Console.WriteLine("請輸入陣列元素的個數:");
string s=Console.ReadLine();
n=Int32.Parse(s);
a=new int[n];
if(n<=20)
break;
else
Console.WriteLine("\n陣列只能夠接收20個元素.\n");
}
Console.WriteLine("");
Console.WriteLine("---------------------------------");
Console.WriteLine("----------請輸入陣列元素---------");
Console.WriteLine("---------------------------------");
//使用者輸入資料
for(int i=0;i<n;i++)
{
Console.Write("<"+(i+1)+">");
string s1=Console.ReadLine();
a[i]=Int32.Parse(s1);
}
}
//顯示陣列內容的函式
void display()
{
Console.WriteLine("");
Console.WriteLine("---------------------------------");
Console.WriteLine("----------排序後的陣列元素-------");
Console.WriteLine("---------------------------------");
for(int j=0;j<n;j++)
{
Console.Write(" "+a[j]);
}
}
//****使用希爾排序的方法
public void ShellSort()
{
for (int step = a.Length/ 2; step >= 1; step = step / 2)
{
for (int i = step; i < a.Length; i+=step)
{
int temp = a[i];
int j = i - step;
while (j >= 0 && temp < a[j])
{
a[j + step] = a[j];
j-=step;
}
a[j + step] = temp;
}
}
}
//交換兩個值的方法
public void swap(int x,int y)
{
int temp;
temp=a[x];
a[x]=a[y];
a[y]=temp;
}
//類的主方法
public static void Main()
{
ShellSorter sec=new ShellSorter();
sec.read();
sec.ShellSort();
sec.display();
Console.WriteLine("\n\n請按任意鍵結束!.");
Console.Read();
}
}