1. 程式人生 > >幾種排序演算法java實現

幾種排序演算法java實現

沒有配圖,過幾天補上

package com.sort;

public class Sort {

	
	
	/**
	 * 插入排序
	 * 原理:往有序的子陣列選擇一個合適的位置插進去
	 * */

	public void insertSort(int sort[]) {
		int temp;
		int j;

		for (int i = 1; i < sort.length; i++) {//迴圈每個數
			temp = sort[i];//要插入數
			for (j = i - 1; j >= 0 && temp < sort[j]; j--) {//前面的子序列都是有序,查詢合適的位置,騰出空位
				sort[j + 1] = sort[j];
			}
			sort[j + 1] = temp;//插入數
		}
	}

	
	/***
	 * 選擇排序
	 * 原理:每次迴圈找出最小的或者最大的
	 * 
	 * */
	public void selectSort(int sort[]) {

		int min;
		int temp;

		for (int i = 0; i < sort.length; i++) {//迴圈一次
			min = i;//假設當前最小
			for (int j = i + 1; j < (sort.length - 1); j++) {//查詢最小的陣列下標
				if (sort[min] > sort[j])
					min = j;
			}
			if (i != min) {//要不是自己所想的那樣就交換
				temp = sort[min];
				sort[min] = sort[i];
				sort[i] = temp;
			}
		}
	}

	
	/**
	 * 氣泡排序基本排版
	 * 原理:每次迴圈,通過與前面的一一比較,遇到比它大或者小的就交換
	 * 
	 * */
	public void bubbleSor(int[] sort) {

		int temp;

		for (int i = 0; i < sort.length; i++)//從陣列下界0到length開始遍歷
			for (int j = (sort.length - 1); j > i; j--) {//每一次從最後往前面開始冒
				if (sort[j] > sort[j - 1]) {
					temp = sort[j];
					sort[j] = sort[j - 1];
					sort[j - 1] = temp;

				}
			}
	}

	// 氣泡排序優化
	public void superDubbleSort(int[] sort) {

		int temp;
		boolean flag = true;//設定變數,記錄上一次有沒有進行交換

		for (int i = 0; i < sort.length && flag; i++) {
			flag = false;

			for (int j = (sort.length - 1); j > i; j--) {
				if (sort[j] > sort[j - 1]) {

					temp = sort[j];
					sort[j] = sort[j - 1];
					sort[j - 1] = temp;
					flag = true;//表示交換過
				}
			}
		}
	}

	
	/**
	 * 希爾排序:插入排序的進階版
	 * 原理:希爾排序是基於陣列基本有序的前提下進行,所謂基本排序是指小的那些在前面,大的那些後面,
	 *     然後設定一把尺子,尺子不斷變小,直至最後到1,這樣每次比較範圍的就逐漸變小了
	 * 
	 * */
	public void shellSort(int sort[]) {

		int temp;
		int increament = sort.length;

		while (increament > 1) {

			increament = increament / 3 + 1;// 變化的尺子
			for (int i = increament; i < sort.length; i++) {//以尺子的增量進行遍歷

				if (sort[i - increament] > sort[i]) {//在尺子的兩端比較兩個數
					temp = sort[i];
					int j;
					for (j = i - increament; j >= 0 && temp < sort[j]; j -= increament) {//將之前排好的序列造出一個合適的位置
						sort[j + increament] = sort[j];
					}
					sort[j + increament] = temp;//插入進去
				}
			}
		}
	}

	/**
	 * 堆排
	 * 原理:堆排是基於大頂堆或者小頂堆進行排序的。每一次迴圈就交換最大數或者最小數放到排好的序列中
	 * 要解決的問題:如果構造大頂堆或者小頂堆,這裡用來二叉的樹的基本性質就是如果一個結果有孩子那就孩子的節點為i 和 i + 1 
	 * 過程:第一步是構造一個頂堆(這裡是大頂堆)
	 *     第二步:迴圈陣列,每一次把子陣列的中最大值挑出來,然後再構造頂堆,如些迴圈
	 * */
	public void heapSort(int sort[]) {

		int i;
		for (i = sort.length / 2; i > 0; i--)
			heapAdjust(sort, i, sort.length - 1);// 先構造大頂堆 , 程式碼往下來

		int temp;
		for (i = (sort.length - 1); i > 1; i--) {//把最大數放在最後一個

			temp = sort[i];
			sort[i] = sort[1];
			sort[1] = temp;
			heapAdjust(sort, 1, i - 1);//把n - 1個的陣列構成頂堆

		}
	}

	// 構造大頂堆
	private void heapAdjust(int[] head, int s, int m) {

		int temp, j;
		temp = head[s];

		for (j = 2 * s; j <= m; j *= 2) {//二叉樹的性質
			if (j < m && head[j] < head[j + 1])//比較父節點與兩個子節點的大小
				++j;
			if (temp >= head[j])
				break;
			head[s] = head[j];
			s = j;
		}
		head[s] = temp;
	}

	/***
	 * 歸併排序
	 * 原理:把一個數組不斷分,分到只有一個為止,然後遞歸回來的時候不斷的合併
	 * 
	 * */ 
	
	
	public void merginSort(int sort[]) {

		mSort(sort, 0, sort.length - 1);//往下看

	}

	private void mSort(int[] data, int left, int right) {

		if (left < right) {

			int center = (left + right) / 2;//一分為二

			mSort(data, left, center);//前面到中間的遞迴
			mSort(data, center + 1, right);//中午到最後的遞迴
			merge(data, left, center, right);//每一次都合併,合併往下看

		}
	}
	// 歸併
	private void merge(int[] data, int left, int center, int right) {

		int[] tmpArr = new int[data.length];//一個臨時陣列

		int mid = center + 1;

		int thrid = left;
		int temp = left;

		while (left <= center && mid <= right) {//每一次挑一個出來,直到到前到的到中間或者後面的部分到了最後面
			if (data[left] <= data[mid]) {
				tmpArr[thrid++] = data[left++];
			} else {
				tmpArr[thrid++] = data[mid++];
			}

		}

		while (mid <= right) {//後面的數繼續新增到臨時陣列
			tmpArr[thrid++] = data[mid++];
		}

		while (left <= center) {//前面部分沒新增的繼續新增到臨時陣列
			tmpArr[thrid++] = data[left++];
		}

		while (temp <= right) {//用有序的替換到無序的
			data[temp] = tmpArr[temp++];
		}

	}

	
	/***
	 * 快排:以一個選定的值分成大小兩部分進行遞迴
	 * 
	 * 
	 * */
	public void quickSort(int[] sort) {

		qSort(sort, 0, sort.length - 1);//往下看
	}

	private void qSort(int[] sort, int low, int high) {

		int privot;//特定值
		if (low < high) {

			privot = partition(sort, low, high);//特值部分進行排序,往後看

			qSort(sort, low, privot - 1);
			qSort(sort, privot + 1, high);
		}

	}

	private int partition(int[] sort, int low, int high) {

		int privotkey;

		privotkey = sort[low]; // 這裡是選取子陣列中的第一個元素

		while (low < high) {//每一次都形成以中間值的為基準,左右都是基本有序

			while (low < high && sort[high] >= privotkey)//從後面開始望前比較,遇到比指定的值小的就跳出來
				high--;

			swap(sort, low, high);//交換

			while (low < high && sort[low] <= privotkey)//然後從前面往後面比較,遇到比指定的小大小就跳出來
				low++;

			swap(sort, low, high);//交換
		}

		return low;

	}
   //交換函式
	private void swap(int[] a, int numA, int numB) {

		int temp = a[numA];
		a[numA] = a[numB];
		a[numB] = temp;

	}

	

}