【資料結構與演算法】八大排序整理(python+java)
阿新 • • 發佈:2018-12-17
1.氣泡排序
氣泡排序很簡單,就是從第一個數開始,把數依次和後面一個數比較,大的數交換位置,直到陣列中最後一個數。
與此同時用end限定陣列的結尾。
arry = [2,4,6,8,1,9,0] def swap(arry,i,j): tem = arry[i] arry[i] = arry[j] arry[j] = tem def bubble_sort(arry): if (arry == None)or(len(arry)< 2): print("1") return for end in range(len(arry)-1,0,-1): for i in range(0,end): if arry[i]>arry[i+1]: swap(arry,i,i+1) print(arry) bubble_sort(arry)
備註:條件三段式:
- a[i]<b[j]?a[i++]:b[j++];
- (條件) ? (符合條件所返回的值) : (不符合條件所返回的值)
2.選擇排序
選擇排序就是假設第i個是最小的數,然後遍歷後面的陣列,選出最小的下標,
然後最小下標和標記的min交換位置,直到所有的都遍歷完
def select_sort(arry): if(arry == None)or(len(arry) <2): return for i in range(0,len(arry)-1): minIndex = i #最小下標預設為i,然後找最小的下標 for j in range(i+1,len(arry)): if arry[j] < arry[minIndex]: minIndex = j swap(arry,i,minIndex) print(arry)
3.插入排序
插入排序就類似於撲克牌,預設前j個數是已經排好序的,每次從i位置選擇一個數進入陣列,從後往前的排序,知道未排序序列=0
def insert_sort(arry): if (arry == None) or (len(arry) < 2): return for i in range(1,len(arry)): for j in range(i-1,-1,-1): if arry[j]>arry[j+1]: swap(arry,j,j+1) print(arry)
4.歸併排序
總體思想:把整個陣列分成兩部分,先左側數排序,然後右側陣列排序,
然後外排的方法排序,全部排序後拷貝回原陣列。
package code;
public class mergeSort {
public static void merge_sort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
merge_sort(arr, 0, arr.length - 1);
}
public static void merge_sort(int[] arr, int l, int r) {
if (l == r) {
return;
}
//(L+R)/2會溢位,改成L+(R-L)/2
int mid = l + ((r - l) >> 1);
// l-r的值右移1位,相當l-r的值除以2取整,位運算快
merge_sort(arr, l, mid);
merge_sort(arr, mid + 1, r);
merge(arr, l, mid, r);
}
public static void merge(int[] arr, int l, int m, int r) {
int[] help = new int[r - l + 1];
int i = 0;
int p1 = l;
int p2 = m + 1;
while (p1 <= m && p2 <= r) {
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= m) {
help[i++] = arr[p1++];
}
while (p2 <= r) {
help[i++] = arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[l + i] = help[i];
}
}
public static void main(String[] args){
int[] ary={9,8,7,6,4,5,6,7};
merge_sort(ary);
for(int i=0;i<ary.length;i++){
System.out.println(ary[i]);
}
}
}
def merge_sort(ary):
if len(ary)<2 or ary==None:
return
sortProcess(ary,0,len(ary)-1)
print(ary)
def sortProcess(ary,L,R):
if L==R:
return
mid = L+((R-L)>>1)
sortProcess(ary,L,mid)
sortProcess(ary,mid+1,R)
merge(ary,L,mid,R)
#外排,預設L-mid已經排好,mid+1-R已經排好
def merge(ary,L,mid,R):
help = [0 for i in range(R-L+1)]
i = 0
p1 = L
p2 = mid + 1
while p1 <= mid and p2 <= R:
if ary[p1] < ary[p2]:
help[i] = ary[p1]
i = i+1
p1 = p1+1
else:
help[i] = ary[p2]
i = i+1
p2 = p2+1
#當有一個越界的時候
while(p1 <= mid):
help[i] = ary[p1]
i = i+1
p1 = p1+1
while(p2 <= mid):
help[i] = ary[p2]
i = i+1
p2 = p2+1
#拷貝回原陣列,注意初始值
for i in range(0,len(help)):
ary[L+i] = help[i]
5.快速排序
快速排序就是涉及到
- 荷蘭國旗問題,把陣列中小於NUM的放到左邊,大於NUM的放到右邊,等於NUM的就不動。
- 對於快速排序來說,每次以最右邊的數為比較,
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
quickSort(arr, 0, arr.length - 1);
}
public static void quickSort(int[] arr, int l, int r) {
if (l < r) {
swap(arr, l + (int) (Math.random() * (r - l + 1)), r);
int[] p = partition(arr, l, r);
quickSort(arr, l, p[0] - 1);
quickSort(arr, p[1] + 1, r);
}
}
public static int[] partition(int[] arr, int l, int r) {
int less = l - 1;
int more = r;
while (l < more) {
if (arr[l] < arr[r]) {
swap(arr, ++less, l++);
} else if (arr[l] > arr[r]) {
swap(arr, --more, l);
} else {
l++;
}
}
swap(arr, more, r);
return new int[] { less + 1, more };
}
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}