1. 程式人生 > >演算法導論--JAVA實現合併排序詳解

演算法導論--JAVA實現合併排序詳解

最近複習演算法的基本知識,主要是看《演算法導論》,根據書本中的虛擬碼寫java程式碼。以下是合併排序的程式碼:

public class MergeSort {
	/**
	 * @Title: merge
	 * @Description:將左右兩個已排序的子數組合併為一個已排序的陣列
	 * @param A
	 * @param p
	 * @param q
	 * @param r
	 * @date 2016年3月3日
	 */
	public static void merge(int[] A, int p, int q, int r) {
		// p為左陣列的起點下標,q為左陣列的終點下標,n1即為左陣列的元素個數
		int n1 = (q - p) + 1;
		// q+1為右陣列的起點下標,r為右陣列的終點下標,n2即為右陣列的元素個數
		int n2 = (r - (q + 1)) + 1;
		// 兩個陣列各加入一個哨兵標誌值,用於標識無牌,所以陣列長度+1
		int[] leftArray = new int[n1 + 1];
		int[] rightArray = new int[n2 + 1];
		// 從原陣列拷貝n1個元素到左陣列
		for (int i = 0; i < n1; i++) {
			leftArray[i] = A[p + i];
		}
		// 從原陣列拷貝n2個元素到右陣列
		for (int i = 0; i < n2; i++) {
			// 右陣列的起點座標為q+1
			rightArray[i] = A[(q + 1) + i];
		}
		// 插入哨兵標誌,書中的虛擬碼為正無窮大,使任何數值與其相比均為較小。(該設計很巧妙,否則要每次判斷子陣列是否遍歷結束)
		// java中應該使用類似Double.POSITIVE_INFINITY的值,此處僅用integer的最大值
		leftArray[n1] = Integer.MAX_VALUE;
		rightArray[n2] = Integer.MAX_VALUE;
		int i = 0, j = 0;
		// 從兩個牌堆中取出牌,比較後合併回A陣列
		// r為整個陣列的最後一個元素的下標,而不是陣列的length,迴圈a.length=r+1次
		for (int k = p; k < r + 1; k++) {
			// 比較左右陣列的第i,第j個元素,把較小值填入原陣列對應k位置,如某子陣列取出較小值,則露出下一個值
			if (leftArray[i] <= rightArray[j]) {
				A[k] = leftArray[i];
				i = i + 1;
			} else {
				A[k] = rightArray[j];
				j = j + 1;
			}
		}

	}

	/**
	 * @Title: sort
	 * @Description:
	 * @param array
	 * @param p
	 * @param r
	 * @date 2016年3月3日
	 */
	public static void sort(int[] array, int p, int r) {
		//如果p>=r,則陣列中至多隻有一個元素,即無需排序。
		if (p < r) {
			// 陣列切分為兩個,找出切分的下標
			int q = (int) Math.floor((p + r) / 2);
			sort(array, p, q);
			sort(array, q + 1, r);
			// 合併
			merge(array, p, q, r);
		}

	}

	public static void main(String[] args) {
		int[] array = { 9, 5, 2, 4, 7, 1, 3, 2, 6 };
		sort(array, 0, array.length - 1);
		System.out.println(Arrays.toString(array));
	}

}

演算法導論中說明該演算法的舉例(紙牌遊戲)很貼切,很方便理解,如下:


附原虛擬碼:


相關推薦

演算法導論--JAVA實現合併排序

最近複習演算法的基本知識,主要是看《演算法導論》,根據書本中的虛擬碼寫java程式碼。以下是合併排序的程式碼: public class MergeSort { /** * @Title: merge * @Description:將左右兩個已排序的子數組合併為

氣泡排序演算法 Java 實現過程及

 氣泡排序(Bubble Sort)是一種簡單的排序演算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢“浮”

演算法導論》紅黑樹(二):Java實現Demo

使用Java簡單地實現紅黑樹,程式碼如下: /** * 紅黑樹實現demo */ public class RedBlackTree<Key extends Comparable<Key>> { private stati

歸併排序java實現(超

歸併排序,見名知意,就是遞迴+合併 原理: 使用遞迴的手段,達到分割的目的,在分割後進行合併,合併也是遞迴的,這就是這裡的雙向過程都是遞迴進行的,結果如圖: 示例(例項): 以一下一串數字為例,首先進行拆分,然後合併,在合併的過程,進行排序,這裡需要說明的是,遞迴在整個過程中都

資料探勘貝葉斯(Bayes)演算法java實現 帶註釋

注:本演算法的實現僅僅適用於小規模資料集的實驗與測試,不適合用於工程應用<span style="font-family: Arial, Helvetica, sans-serif;"> 演算法假定訓練資料各屬性列的值均是離散型別的。若是非離散型別的資料,需要

Java實現合併排序

/** * 測試方法 * * @param args */ public static void main(String[] args) { int[] array = new int[]{2, 5, 1

資料結構與演算法分析之----各種常用排序

package cn.qunye.Sort_排序; import java.util.ArrayList; import java.util.List; /** * 合併排序: * 將待排序元素分成大小大致相同的兩個子集合,分別對兩個子集進行合併排序,最終將排好序的子集合併成所要求的排好序的集合 *

演算法導論之矩陣鏈乘法

內容都是是演算法導論上的,僅作為一個閱讀筆記,記錄一下自己閱讀過程中碰到的一些問題。希望能對需要的同學有所幫助! 矩陣鏈乘法是指給定一個n個矩陣的序列(矩陣鏈)< A1, A2, …, An>,我們希望計算它們的乘積 A1A2A3…An

演算法導論學習--紅黑樹之刪除(含完整紅黑樹程式碼)

前面我們討論了紅黑樹的插入的實現,基本思想是分類討論;然後分情況討論以後我們發現插入操作調整函式只需要處理三種情況,並不是太複雜。但是刪除操作會更復雜一點,因為二叉搜尋樹的刪除操作本身就分成了多種情況,這樣在執行刪除操作後要處理的情況會更多;下面對於刪除操作我們

演算法導論2.4 合併排序求逆序數

2-4 逆序對     設A[1...n]是一個包含n個不同數的陣列。如果在i<j的情況下,有A[i]>A[j],則(i,j)就稱為A中的一個逆序對。     (1)列出陣列{2,3,8,6,1}的五個逆序。     (2)如果陣列的元素取自{1,2...,n}

java 直接插入排序

1.直接插入排序比較簡單就不做更多的介紹了 請看程式碼: public static void insertSort(int[] arr) { for (int i = 1; i < arr.length; i++) { int temp =arr[

【資料結構與演算法】之排序全家桶(十大排序及其Java實現)---第七篇

本篇文章彙總了10種場常見的排序演算法,篇幅較長,可以通過下面的索引目錄進行定位查閱: 7、桶排序 一、排序的基本概念 1、排序的定義 排序:就是使一串記錄,按照其中的某個或者某些關鍵字的大小,遞增或遞減的排列起來

插入排序演算法java實現版)

插入排序分為兩種,直接插入排序和二分插入排序,本節我們只介紹直接插入排序。這兩種插入排序實際上都是插入排序,唯一的不同就是插入的方式不一樣。 插入排序就是往數列裡面插入資料元素。一般我們認為插入排序就是往一個已經排好序的待排序的數列中插入一個數,使得插入這個數之後,數列仍然有序。 二分插入排序也是用了分

必須知道的八大種排序演算法java實現】(三) 歸併排序演算法、堆排序演算法

一、歸併排序演算法 基本思想:   歸併(Merge)排序法是將兩個(或兩個以上)有序表合併成一個新的有序表,即把待排序序列分為若干個子序列,每個子序列是有序的。然後再把有序子序列合併為整體有序序列。 歸併排序示例:   合併方法: 設r[i…n]由兩個有序子表r[i…m]和r[m+1…n]組

必須知道的八大種排序演算法java實現】(二) 選擇排序,插入排序,希爾演算法

一、選擇排序   1、基本思想:在要排序的一組數中,選出最小的一個數與第一個位置的數交換;然後在剩下的數當中再找最小的與第二個位置的數交換,如此迴圈到倒數第二個數和最後一個數比較為止。   2、例項   3、演算法實現    /** * 選擇排序演算法 * 在未

Java常見排序演算法之選擇排序

一、簡介 選擇排序,就是每一趟從待排序的序列中選出最小的元素,順序放在已排好序的序列最後,直到全部序列排序完畢。簡單理解就是假設一個最小值,將剩餘的未排序的序列與假設的最小值進行比較,如果發現比假設的最小值還小的值,那麼將它與假設的最小值調換位置。 二、排序思路 排序思

Java常見排序演算法之插入排序

一、簡介 插入排序,就是假定一個參考值,假設該參考值左邊的元素都有序,那麼從該元素開始從後往前挨個查詢,如果找到比參考值大的數,那麼就將這個大的數後移,如果未找到比參考值大的數,說明不用移動元素。迴圈比較,這樣經過比較後移之後就會空出下標為0的位置,用於存放這個參考值。

java實現的歸併排序

歸併排序的基本原理為: 一:拆分,假設有N個元素的列表,將這個列表拆分成2個或兩個以上元素組成的新的列表,然後分別對子列表進行排序 二:歸併,把所有的排好序的子類表兩兩歸併,如此重複,直到歸併成一個含N個有序列表為止 歸併排序其實和快速排序都是同一種思想的排序演算法,其採用

基數排序以及java實現

前言 基數排序(radix sort)又稱桶排序(bucket sort),相對於常見的比較排序,基數排序是一種分配式排序,即通過將所有數字分配到應在的位置最後再覆蓋到原陣列完成排序的過程。我在上一篇講到的計數排序也屬於這種排序模式,上一篇結尾處提到了計數排序的穩定性,即排序前和排序後相同的數字相對位置保持

插入排序Java實現

一、基本思想     插入排序(Insertion-Sort)的演算法描述是一種簡單直觀的排序演算法。它的工作原理是通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃描,找到相應位置並插入。 二、演算法描述     1.從第一個元素開始,該元素可以認為已經被