@資料結構複習筆記(一):
這是我的第一天的學習日記——今天主要學的是排序,這裡我們就簡單的講一下幾種常見的排序:
先來看排序的輸入輸出:
給定乙個任意無序定長陣列num[10]=
通過**處理後陣列將變成:
看似簡單的過程:可以有很多種處理的方法:
先看看第一種排序:
這種排序演算法的思路就是 將下乙個需要排的元素插入到之前已排好的陣列中去
例如:結束排序
為了提高效率會附設乙個監視哨num[0],監視哨有兩個作用1.備份待插入的記錄,2.防止越界
插入排序的**:
void
insertsort
(int num,
int len)
num[j +1]
= k;
}print
(num, len);}
;
不難發現插入排序難點在於尋找插入的位置,其實也就不難發現這是乙個可以在查詢上進行優化的乙個演算法。
對於查詢演算法的優化,我們不難想到折半查詢法,也就衍生了折半插入排序,這裡**不做展示了。(自己懶,沒寫)
桶排序在某種意義上來說,是效率較高的排序演算法,時間複雜度近似o(n).
這裡先分析演算法的方法:此演算法需要知道範圍,將範圍轉化為桶個數,遍歷一遍陣列,每碰到乙個數,就把它扔進相應的桶中(socket[num]++),然後按照每個桶裡的數的個數放入原陣列。此時排序完成。
當然也可以從空間上優化桶排序
(此處指桶排序中,範圍的個數為桶數的十倍或百倍(整數倍)然後在桶外進行桶排序,桶內進行快速排序)
分析一下時間複雜度:
為啥說是近似o(n):
假設有n個數,範圍為m(即有m個桶)
初始化桶:m
陣列放入桶中:n
桶內排序:(一般採用快速排序)nlog(n/m) //n個桶,每個桶內個數為n/m
最後放回陣列:n
實際上的複雜度為:o(2n+m+nlog(n/m))
去掉係數:o(n+m+n(log n - log m))
假設桶的個數等於數的個數(即保證一數一桶)
此時,時間複雜度為o(m+n),近似o(n)
上**
void
socketsort
(int num,
int len)
for(
int i =
11; i >
0; i--)}
cout << endl;
}
最簡單的排序:
每一輪排序都選出剩下數中最大的,將其放在最後,選擇的方法是:每相鄰的兩個數進行比較,大的就放在後面,這樣每次進行到最後,交換到最後的數一定是該輪最大的
例如此處對1,3先進行比較發現3大,把3放在後面,然後對3,2進行比較,發現3大,交換兩數的位置即
還需要進行比較,後面的比較就不做演示了
上**
void
bubblesort
(int num,
int len)}}
print
(num, len)
;}
選擇排序的思路:進行多輪選擇,每輪將通過比較最大的數選出來,先標記下來,在此輪最後,標記的數即為本輪最大,放在最後
此方法時間複雜度和冒泡一樣都為o(n^2)
例如第一輪max先等於1,進行本輪比較,遇到3時,3大,所以現在max=3,最後遇到4,發現4大,max=4
現在把max放在陣列尾部,完成第一輪。
此時:第二輪
max還是先等於1,進行本輪比較之後,max最後等於3此時將末尾與3交換位置
此時後面還需比較,此處不做講解
上**
void
selectsort
(int num,
int len)}if
(max != i)
}print
(num, len);}
;
目前來說,比較熱門的排序,基於快速排序,能解決很多問題,比如比較出名的荷蘭國旗問題,就是一趟快速排序解決的。還有bfprt演算法也是基於快速排序的(分組快排+特殊基準值)。
現在來看看快速排序的思路:每一趟快速排序,將會選取乙個基準數,然後遍歷陣列,此處遍歷陣列需要三個指向值。
start:標記陣列的頭
end:標記陣列的尾部
current:可以不需要,為了方便理解,這裡加個current變數,即記錄當前遍歷的值
每一趟快排的思想就是將current的值與基準值進行比較,比基準值大將放在基準值的右邊,比基準值小就放在左邊
放置數就需要start標記和end標記,用current與start或end交換,交換完之後start,end往中間靠
然後對一趟快排之後的陣列,按基準值分割開,分別遞迴
例如選取2為基準
一趟快排結束:
然後對左右遞迴
最後交換到最後
上**:
void
quicksort
(int
* num,
int start,
int end)
int i, j, base, temp;
i = start;
j = end;
base = num[start]
;while
(i} num[start]
= num[i]
; num[i]
= base;
quicksort
(num, start, i -1)
;quicksort
(num, i+
1, end);}
;
// datastructuretest.cpp : 此檔案包含 "main" 函式。程式執行將在此處開始並結束。
/* 詳解排序演算法:
測試資料:
輸出:
*///
#include
using
namespace std;
void
print
(int num,
int len)
;void
insertsort
(int num,
int len)
;void
socketsort
(int num,
int len)
;void
bubblesort
(int arr,
int n)
;void
quicksort
(int
* num,
int start,
int end)
;void
selectsort
(int num,
int len)
;int
main()
;//print(num, 10);
//bubblesort(num, 10);
//insertsort(num,10);
//socketsort(num,10);
//selectsort(num,10);
int num1[10]
=;print
(num1,10)
;quicksort
(num1,0,
9);print
(num1,10)
;}void
insertsort
(int num,
int len)
num[j +1]
= k;
}print
(num, len);}
;void
print
(int num,
int len)
cout << endl;};
void
socketsort
(int num,
int len)
for(
int i =
11; i >
0; i--)}
cout << endl;
}void
bubblesort
(int num,
int len)}}
print
(num, len);}
void
selectsort
(int num,
int len)}if
(max != i)
}print
(num, len);}
;void
quicksort
(int
* num,
int start,
int end)
int i, j, base, temp;
i = start;
j = end;
base = num[start]
;while
(i} num[start]
= num[i]
; num[i]
= base;
quicksort
(num, start, i -1)
;quicksort
(num, i+
1, end);}
;
資料結構與演算法複習 一 排序演算法
這篇文章將會介紹常見的排序演算法 使用 c 實現 將陣列分為有序區 左邊 和無序區 右邊 在初始化時有序區為空,無序區包含陣列所有元素 每次從無序區的最後乙個元素開始,一直向前冒泡到無序區的第乙個位置,使其變成有序 templatevoid swap e a,int i,int j template...
資料結構系列 一 排序演算法
1.2 插入排序 1.3 選擇排序 1.4 歸併排序 1.5 堆排序 1.6 快速排序 基於資料狀況的排序演算法 1.7桶排序 1.8 小結 穩定排序 相對次序並沒有改變 void bubblesortv1 int a,int n 實現 增加乙個sorted標誌,對於有序陣列則不再進行比較判斷。複雜...
資料結構《一》 排序演算法之氣泡排序
氣泡排序可以說是最簡單,大多數人最先接觸的排序演算法。臨近的數字兩兩進行比較,按照規定的順序進行交換,這樣一趟過去後,最大或最小的數字就像氣泡一樣被 排 最後一位,然後第二趟之後,次大或次小的數字被 排 到倒數第二位,以此類推,直至第一位與第二位順序正確。實現過程如圖 氣泡排序複雜度為o n 過程如...