1. 程式人生 > >資料結構牛客筆記2

資料結構牛客筆記2

隨機快排

時間複雜度O(N*logN)

空間複雜度O(logN):最好情況為O(logN),二分法打斷點;最壞情況下為O(N),每個都要打斷點。

樣本狀況

一個樣本狀況會導致演算法的複雜度有所變化,可以採用兩種方法:

1、隨機樣本選取來劃分

2、雜湊函式

堆就是完全二叉樹。

大根堆

任何一棵子樹的最大值都是樹的頭部。

小根堆

任何一棵子樹的最小值都是樹的頭部。

堆排序

1、先生成一個大根堆。

2、然後把大根堆的根與最後一個值交換。

3、讓堆的大小-1,再做heapfiy的過程,重新形成大根堆。

4、再把最大值放到最後面。以此類推。

作業

1、完成荷蘭國旗問題。

在這裡插入圖片描述

2、經典快排、隨機快排

3、heapinsert 和 heapify

heapinsert:插入最大堆,是建立堆的一個操作。

heapify:改變陣列中的某一值重新調整為最大堆。

作業完成

1、荷蘭國旗問題

package niuke2;

public class helanguoqi {
	
	public static void helan(int[] arr, int num) {
		int left = 0;
		int right = arr.length - 1;
		int less = left - 1
; int more = right + 1; while(left < more) { if(arr[left] < num) { swap(arr,++less, left++); }else if(arr[left] > num) { swap(arr, --more, left); }else { left++; } } } //交換元素 public static void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]
; arr[index1] = arr[index2]; arr[index2] = tmp; } //列印陣列,測試用。 public static void printarr(int[] arr) { for(int i = 0; i <= arr.length-1; i++) { System.out.print(arr[i] + " "); } System.out.println(" "); } public static void main(String[] args) { int[] res = {0,0,0,0,0,0,0,0,0,0}; for(int i = 0; i < 10; i++) { int ran = (int) (Math.random()*10 +8) - (int) (Math.random()*10 +2); res[i] = ran; } printarr(res); System.out.println("num = " + res[3]); helan(res,res[3]); printarr(res); } }

2、經典快排

經典快排思路跟荷蘭國旗問題一樣,只是注意要最後分割槽時要換位置。最壞情況:O(N2),最好情況:O(NlogN)。

package niuke2;

import java.util.Arrays;

public class QuickSort {

	public static void quickSort(int[] arr) {
		if(arr.length <= 1)
			return;
		quicksort(arr, 0, arr.length-1);
	}
	
	public static void quicksort(int[] arr, int left, int right) {
		if(left < right) {
			int p = quickSort(arr,left,right);
			quicksort(arr, left, p-1);
			quicksort(arr, p+1, right);
		}
	}
	
	public static int quickSort(int[] arr, int left, int right) {
		if(left >= right)
			return 0;
		int num = arr[right];
		int less = left - 1;
		int more = right;
		while(left < more) {
			if(arr[left] < num) {
			swap(arr,++less,left++);
			}else if(arr[left] > num) {
				swap(arr,--more,left);
			}else {
				left++;
			}
		}
		swap(arr,more,right);
		return left;
	}
	
	//交換元素
	public static void swap(int[] arr, int index1, int index2) {
		int tmp = arr[index1];
		arr[index1] = arr[index2];
		arr[index2] = tmp;
	}
			
	//列印陣列,測試用。
	public static void printarr(int[] arr) {
		for(int i = 0; i <= arr.length-1; i++) {
			System.out.print(arr[i] + "  ");
		}
		System.out.println(" ");
	}	
	
	//比較陣列,測試用。
	public static void Compare(int[] a1, int[] a2) {
		if(Arrays.equals(a1, a2)) {
			System.out.println("Nice!");
		}else {
			System.out.println("Fucking Fucked!");
		}
	}
	
	public static void main(String[] args) {
		
		int[] res = {0,0,0,0,0,0,0,0,0,0};
		int[] res1 = {0,0,0,0,0,0,0,0,0,0};
 		for(int i = 0; i < 10; i++) {
			int ran = (int) (Math.random()*10 +8) - (int) (Math.random()*10 +2);
			res[i] = ran;
			res1[i] = ran;
		}
 		Arrays.sort(res1);
 		quickSort(res);
 		Compare(res, res1);
	}
}

3、隨機快排

隨機快排的時間複雜度遠遠優於經典快排,因為它所篩選的標誌時隨機的,在概率上求期望,時間複雜度能到達O(nlogn)

package niuke2;

import java.util.Arrays;

public class QuickSortrandom {

	public static void quickSort(int[] a) {
		if(a.length < 2) {
			return;
		}
		quickSort(a,0,a.length-1);
	}
	
	public static void quickSort(int[] a,int left, int right) {
		if(left < right) {			
			int ran = (int)(Math.random() * (right - left + 1));
			swap(a, left + ran,right);
			int[] num = quicksort(a,left,right);
			quickSort(a, left, num[0] - 1);
			quickSort(a, num[1] + 1, right);
		}
	}
	
	public static int[] quicksort(int[] a,int left, int right) {
		int less = left -1;
		int more = right;
		int num = a[right];
		while(left < more) {
			if(a[left] < num) {
				swap(a, ++less,left++);
			}else if(a[left] > num) {
				swap(a,--more,left);
			}else {
				left++;
			}
		}
		swap(a,right,more);
		return new int[] {less + 1,more};
	}
	
	//交換元素
	public static void swap(int[] arr, int index1, int index2) {
		int tmp = arr[index1];
		arr[index1] = arr[index2];
		arr[index2] = tmp;
	}

	//列印陣列,測試用。
	public static void printarr(int[] arr) {
		for(int i = 0; i <= arr.length-1; i++) {
			System.out.print(arr[i] + "  ");
		}
		System.out.println(" ");
	}	
	
	//比較陣列,測試用。
	public static void Compare(int[] a1, int[] a2) {
		if(Arrays.equals(a1, a2)) {
			System.out.println("Nice!");
		}else {
			System.out.println("Fucking Fucked!");
		}
	}
	
	public static void main(String[] args) {
		
		int[] res = {0,0,0,0,0,0,0,0,0,0};
		int[] res1 = {0,0,0,0,0,0,0,0,0,0};
 		for(int i = 0; i < 10; i++) {
			int ran = (int) (Math.random()*10 +8) - (int) (Math.random()*10 +2);
			res[i] = ran;
			res1[i] = ran;
		}
 		Arrays.sort(res1);	
 		quickSort(res);
 		Compare(res, res1);
	}
}