【Data Structure】nlogn-SortMethods(Quick/Heap/Shell/Merge)

排序算法有很多,主要有: 

一、插入排序(包括ShellSort希爾排序)

二、選擇排序(包括HeapSort堆排序)

三、快速(Quick)排序

四、歸併(Merge)排序

五、基數排序 

每個人排序的分類也不同。

這裏針對一些先進的算法(時間複雜度nlogn)進行一些總結(Given in the form of C language)。

QuickSort/HeapSort/ShellSort/MergeSort

1.QuickSort

#pragma once

#include "Swap.h"

typedef int ElemType;

int Partition(ElemType arr[], int low, int high) {

	int pivotkey = arr[low];

	while (low < high) {

		while (low < high && arr[high] >= pivotkey)
			--high;

		Swap(arr[low], arr[high]);

		while (low < high && arr[low] <= pivotkey)
			++low;

		Swap(arr[high],arr[low]);

	}
	

	return low;
}

void QSort(ElemType arr[], int low, int high) {

	int pivotloc = 0;

	if (low < high) {

		pivotloc = Partition(arr, low, high);

		QSort(arr, low, pivotloc - 1);
		QSort(arr, pivotloc + 1, high);

	}
	
}

void QuickSort(ElemType arr[], int length) {

	QSort(arr, 0, length - 1);

}

2.HeapSort

#pragma once

#include "Swap.h"
#include "LT.h"

typedef int HeapType;

void HeapAdjust(HeapType arr[], int s, int m) {

	int rc = arr[s];

	for (int j = 2 * s ; j <= m; j *= 2) {

		if (j < m && LT(arr[j], arr[j + 1]))
			++j;

		if (!LT(rc, arr[j]))
			break;

		arr[s] = arr[j];
		s = j;

	}

	arr[s] = rc;

}

void HeapSort(HeapType arr[], int length) {

	for (int i = length / 2 - 1; i >= 0; --i)
		HeapAdjust(arr, i, length);

	for (int i = length - 1; i > 0; --i) {

		Swap(arr[0],arr[i]);

		HeapAdjust(arr, 0, i - 1);

	}
		
}

3.ShellSort

#pragma once

#include "LT.h"

typedef int Elemtype;

void ShellInsert(Elemtype arr[], int dk,int length) {

	int i, j, temp;

	for (i = dk; i < length; ++i)

		if ( LT(arr[i], arr[i - dk]) ) {

			temp = arr[i];

			for (j = i - dk; j > 0 && LT(temp, arr[j]); j -= dk)
				arr[j + dk] = arr[j];

			arr[j + dk] = temp;

		}

}

void ShellSort(Elemtype arr[], int dlta[], int t,int length) {

	for (int k = 0; k < t; ++k)
		ShellInsert(arr, dlta[k],length);

}

4.MergeSort

#pragma once

typedef int RcdType;

void Merge(int arr[], int tarr[], int start, int mid, int end) {

	int i = start, j = mid + 1, k = 0, m = mid, n = end;

	while (i <= m && j <= n)
	{
		if (arr[i] <= arr[j])
			tarr[k++] = arr[i++];
		else
			tarr[k++] = arr[j++];
	}

	while (i <= m)
		tarr[k++] = arr[i++];

	while (j <= n)
		tarr[k++] = arr[j++];

	for (i = 0; i < k; i++)
		arr[start + i] = tarr[i];

}

void MSort(RcdType arr[], RcdType tarr[], int start, int end) {

	if (start < end) {

		int mid = (start + end) / 2;

		MSort(arr, tarr, start, mid);
		MSort(arr, tarr, mid + 1, end);

		Merge(arr, tarr, start, mid, end);

	}

}

void MergeSort(int arr[],int n) {

	int tarr[10];

	MSort(arr, tarr, 0, n - 1);

}

LT.h 比較a和b的大小

#pragma once

bool LT(int a, int b) {

	if (a < b)
		return true;

	return false;

}

Swap.h 交換a和b的值

#pragma once

void Swap(int &a, int &b) {

	int t = a;
	a = b;
	b = t;

}

以上代碼用Main.cpp驗證

#include <stdio.h>

#include "QuickSort.h"
#include "HeapSort.h"
#include "ShellSort.h"
#include "MergeSort.h"

#define SIZE 10
#define DSIZE 3

int main() {

	int a[SIZE] = { 3,5,8,2,7,4,9,6,1,10 }; // An Example

	for (int i = 0;i < SIZE; ++i)
		printf("%d ", a[i]);

	printf("\n");

	QuickSort(a, SIZE); // QuickSort

	HeapSort(a,SIZE); //HeapSort

	int dlta[DSIZE] = { 5,3,1 }; //假定設此組步長
	ShellSort(a, dlta, DSIZE, SIZE); //ShellSort

	MergeSort(a, SIZE); //MergeSort

	for (int i = 0;i < SIZE; ++i)
		printf("%d ", a[i]);

	printf("\n");
	return 0;

}

以上所列算法的O(n) = nlogn,但該MergeSort(又稱二路歸併)以遞歸形式調用,實用性較差。

實際中多采用QuickSort




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章