資料結構回顧 排序

2021-10-08 11:40:34 字數 4446 閱讀 9542

要求:掌握演算法思想,效能分析,**實現

注:本文預設遞增排序

一,排序的基本概念

1,什麼是排序:將乙個沒有順序的數列進行重新排列是它成為乙個遞增(遞減)序列

2,穩定性:如果數列中有兩個元素的值是相等的,排序後他們的相對位置沒有發生改變,就認為該排序演算法穩定。

3,內部排序:指排序期間元素全部存放在記憶體中的排序

外部排序:排序期間元素無法全部同時存放在記憶體中,必須在排序過程中根據要求不斷在內,外存之間進行移動

插入排序:每次將乙個待排序的序列插入到乙個前面已經排好的子串行中

設已知數列[ a1 a2,,,ai,,,,an],已知a1,,,ai已經是遞增序列了,如何將ai+1號元素插入到a1,,,ai中使得,它們任然是有序序列

思想:

**實現:

void insertsort(int a,int n)

for(j=i-1;j>=high+1;j--)//向後移動元素

a[j+1]=a[j];

a[high+1]=a[0];//插入元素

}}

效能分析:

思想:先將排序表分割成d個形如  [i,i+d,i+2d,i+3d,,,,i+kd]的特殊子表,分別進行直接插入排序,當整個表中元素已經基本有序時,再對全體記錄進行一次直接插入排序。

**實現:

void shellsort(int a,int n)

if(flag==false)

return;//是遞增序列,結束迴圈

} }for(int k=0;k效能分析:

思想:在排序表【1,,,n】中任取乙個元素pivot作為基準,通過一趟排序將待排序表劃分為兩個部分,pivot前面的元素均小於它,後面的元素均大於它。所以一次劃分會讓當前的pivot元素歸位,進行對已經劃分的部分進行相同操作,知道每乙個元素歸位。

一次劃分實現思路:

**實現:

int partition(int a,int low,int high)

} a[0]=a[k]; }

void buildmaxheap(int a,int len)

}void heapsort(int a,int len)

for(int k=0;k0&&a[i]效能分析:

思想:將相鄰的兩組序列進行有序的歸併。開始時乙個元素為一組,n個元素為n組,然後將相鄰i號元素和i+1號元素歸併成有序序列,就出現n/2組,繼續對他們進行歸併出現n/4組,,,,直到歸為一組為止。

**實現:

(**有問題)

void merge(int a,int low,int mid,int high);

sort1(a);

system.out.println("====》直接插入排序");

sort2(a);

system.out.println("====》折半插入排序");

sort3(a);

system.out.println("====》希爾排序");

sort4(a);

system.out.println("====》選擇排序");

sort5(a);

system.out.println("====》堆排序");

sort6(a);

system.out.println("====》氣泡排序");

// sort7(a,0,a.length-1);

// show(a);

// system.out.println("====》快速排序");

sort8(a,0,a.length-1);

show(a);

system.out.println("====》歸併排序");

}/**

* 方法:直接插入排序

* 思想:

* 預設第乙個元素是有序列表。

* 記錄要排序的元素temp=a[i]

* 從第二個元素開始,和順序表中的元素進行比較,找到可以插入元素的位置。

* 把有序列表中大於temp的元素後移乙個位置,空出插入的位置

* 插入元素

*/static void sort1(int a)

a[j+1] = temp; //插入,此處的arr[j+1]其實是上邊的「arr[j]」,執行了乙個j--操作

}show(a);

}/**

* 方法:折半插入

* 思想:

* 記錄要插入的元素temp=a[i]

* 對前面有序列表折半查詢可以插入的位置,

* 將有序列表中比temp大的元素後移一位,流出乙個空間插入temp元素

*/public static void sort2(int a)

//將a[low]--a[i-1]的數都想後移一位,插入元素的位置空出來

for (int j = i; j > low; j--)

a[low] = temp; //最後將a[i]插入a[low]

}show(a);

}/**

* 方法:希爾排序

* 思想:

* i從0+d開始,因為分組後的第一組是0,d,2d,3d...這樣乙個序列.所以直接從d開始比較

* 此迴圈比較演算法區別:假設有乙個16項陣列,下標為0~15,當d=5時,分為5組

* 以下標表示:(0,5,10,15),(1,6,11),(2,7,12),(3,8,13),(4,9,14)

* 如果分別針對每一組插入排序,則下標控制很複雜,所以外層for迴圈每次對每一分組的前2個資料排序

* 然後前3個,然後前4個...這和組數有關

* 即當i=5時,對(0,5,10,15)中的(0,5)排序

* i=6時,對(1,6,11)中的(1,6)排序.....

* i=10時,對(0,5,10,15)中的(0,5,10)排序......

* 一直到d=1時,此時的陣列基本有序,資料項移動次數大大減少

* */

public static void sort3(int a)

a[j] = temp;

}d = d / 2;

}show(a);

}/**

* 選擇排序,每次從後面無序列表中選出最小值插入前方有序列表

* @param a

*/public static void sort4(int a)

}if (k != i)

}show(a);

}/**

* 堆排序

* @param a

*/public static void sort5(int a) }}

show(a);

}/**

* 氣泡排序

* @param a

*/public static void sort6(int a) }}

show(a);

}/**

* 快速排序

* @param a

* @param low

* @param high

* @return

*/public static int sort7(int a, int low, int high)

return a;

}public static int getmiddle(int a,int low, int high)

a[low] = a[high];

//從左往右找比基準大的元素並交換

while (lowa[high] = a[low];

}a[low] =temp;

return low;

}/**

* 歸併排序

*/public static int sort8(int a,int left,int right)

return a;

}private static void merge(int a, int left, int middle, int right)else

}//剩餘部分以此放入臨時陣列。以下兩個while只會執行其中乙個

while (left<=middle)

while (rightindex<=right)

//將臨時陣列中的內容拷貝回原陣列

while (tmp<=right)

}public static void show(int a)

}}

資料結構與演算法 堆排序演算法回顧

堆排序是利用堆這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序,它的最壞,最好,平均時間複雜度均為o nlogn 它也是不穩定排序。堆排序的應用場景主要有 topk問題,優先順序佇列等。原理 1.將存放在array 0,n 1 中的n個元素建成初始堆 2.此時,堆頂元素該堆的最大值 3.將堆...

資料結構 樹的回顧

度 結點擁有的子樹數就稱為結點的度。度為0的結點稱為葉子結點或終端結點。度不為0的結點稱為非終端結點或分支結點。樹的度為樹內各結點度的最大值。樹的層次 結點的層次從根開始定義起,根為第一層,根的孩子為第二層。若某結點在第l層,則其子樹的根就在l 1層。樹的高度 樹中結點的最大層次稱為樹的深度或高度。...

回顧資料結構 鍊錶

鍊錶真不是個東西 附上靈魂畫圖一張 private node dummyhead 虛擬頭節點 int size 無參建立鍊錶 public linkedlist 建立鍊錶,並將陣列放到鍊錶上 public linkedlist e e 獲得鍊錶長度 public int getsize 判斷是否為空...