1. 程式人生 > >交換排序:氣泡排序、選擇排序【排序演算法】

交換排序:氣泡排序、選擇排序【排序演算法】

氣泡排序基本思想:

在要排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換。

快速排序基本思想:

1)選擇一個基準元素,通常選擇第一個元素或者最後一個元素

2)通過一趟排序講待排序的記錄分割成獨立的兩部分,其中一部分記錄的元素值均比基準元素值小。另一部分記錄的 元素值比基準值大。

3)此時基準元素在其排好序後的正確位置

4)然後分別對這兩部分記錄用同樣的方法繼續進行排序,直到整個序列有序。

快速排序是目前基於比較的內部排序中被認為是最好的方法,當待排序的關鍵字是隨機分佈時,快速排序的平均時間最短;快速排序是一個不穩定的排序方法。

快速排序之所比較快,因為相比氣泡排序,每次交換是跳躍式的。每次排序的時候設定一個基準點,將小於等於基準點的數全部放到基準點的左邊,將大於等於基準點的數全部放到基準點的右邊。這樣在每次交換的時候就不會像氣泡排序一樣每次只能在相鄰的數之間進行交換,交換的距離就大的多了。因此總的比較和交換次數就少了,速度自然就提高了。當然在最壞的情況下,仍可能是相鄰的兩個數進行了交換。因此快速排序的最差時間複雜度和氣泡排序是一樣的都是O(N2),它的平均時間複雜度為O(NlogN)。

各排序演算法比較:


程式碼如下,親測有效:

#include <iostream>
using namespace std;

void swap(int *, int *);
void print(int[], int);
void bubbleSort(int[], int);
void bubbleSort2(int[], int);
void bubbleSort3(int[], int);
void quickSort1(int[], int, int);
void quickSort2(int[], int, int, int);

int main(void){

	int arr[10] = { 49, 38, 65, 97, 76, 13, 27, 49, 55, 04 };
	cout << "Original Array: " << endl;
	print(arr, 10);
	bubbleSort3(arr, 10);
	cout << "bubbleSort results: " << endl;
	print(arr, 10);
	quickSort2(arr, 0, 9, 8);
	cout << "quickSort results: " << endl;
	print(arr, 10);
	return 0;
}

//列印陣列
void print(int a[], int n){
	for (int index = 0; index < n; ++index)
		cout << a[index] << "  ";
	cout << endl;
}

//交換
void swap(int *num1, int *num2){
	int tmp = *num1;
	*num1 = *num2;
	*num2 = tmp;
}

//氣泡排序
void bubbleSort(int array[], int n){
	for (int i = 0; i < n; ++i)
		for (int j = 1; j < n - i;++j)
		if (array[j] < array[j - 1])
			swap(array[j], array[j - 1]);
}

//氣泡排序2,設定一個標誌位flag,當在排序到某一刻已經沒有交換的時候,說明已經有序,把flag置為false,退出排序
void bubbleSort2(int array[], int n){
	bool flag = true;
	int sizeOfArray = n;
	while (flag){
		flag = false;
		for (int j = 1; j < sizeOfArray; ++j){
			if (array[j - 1] > array[j]){
				swap(array[j], array[j - 1]);
				flag = true;
			}
		}
		--sizeOfArray;
	}
}

//氣泡排序3,記錄每次排序最後一次交換元素的位置,在這個位置之後一定是有序的,無需再排,只需排此位置之前的
void bubbleSort3(int array[], int n){
	int flag = n;
	while (flag > 0){
		int sizeOfUnsorted = flag;//上次排序最後一次交換的位置
		flag = 0;
		for (int index = 1; index < sizeOfUnsorted; ++index){
			if (array[index - 1] > array[index]){
				swap(array[index - 1], array[index]);
				flag = index;
			}
		}
	}
}

//快速排序1
void quickSort1(int array[], int left, int right){
	if (left < right){
		int i = left, j = right;
		int base = array[left]; //將最左邊的數作為基準書,儲存在base中
		while (i < j){
			while (i < j && array[j] >= base) //從右向左找第一個比base小的數,找到之後放到base的左邊(與base交換)
				--j;
			while (i < j && array[i] <= base) //從左向右找第一個比base大的數,找到之後放到base的右邊(與base交換)
				++i;
			if (i < j)
				swap(array[i], array[j]);
		}
	//	array[left] = array[i];
	//	array[i] = base;
		quickSort1(array, left, i - 1); //遞迴呼叫
		quickSort1(array, i + 1, right);
	}
}

//快速排序2
void quickSort2(int array[], int left, int right, int k){
	if (right - left > k){
			int i = left, j = right;
			int base = array[left]; //將最左邊的數作為基準書,儲存在base中
			while (i < j){
				while (i < j && array[j] >= base) //從右向左找第一個比base小的數,找到之後放到base的左邊(與base交換)
					--j;
				while (i < j && array[i] <= base) //從左向右找第一個比base大的數,找到之後放到base的右邊(與base交換)
					++i;
				if (i < j)
					swap(array[i], array[j]);
			}
	//		array[left] = array[i];
	//		array[i] = base;
			quickSort2(array, left, i - 1, k); //遞迴呼叫
			quickSort2(array, i + 1, right, k);
	}
	for (int index = 1; index <= right; ++index){	//此時的序列已基本有序,再用插入排序對基本有序序列排序
		int tmp = array[index];
		int j = index - 1;
		if (tmp < array[j]){
			array[j + 1] = array[j];
			--j;
		}
		array[j + 1] = tmp;
	}
}
</pre><pre name="code" class="cpp">
<span style="font-family:Microsoft YaHei;font-size:14px;">執行結果:</span>
<img src="https://img-blog.csdn.net/20150908194202423?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

相關推薦

資料結構實驗之圖論十一AOE網上的關鍵路徑Bellman_Ford演算法

Problem Description     一個無環的有向圖稱為無環圖(Directed Acyclic Graph),簡稱DAG圖。     AOE(Activity On Edge)網:顧名思義,用邊表示活動的網,當然它也是DAG。與AOV不同

交換排序氣泡排序選擇排序排序演算法

氣泡排序基本思想: 在要排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換。 快速排序基本思想: 1)選擇一個基準元素,通常選擇第一

程式設計基礎知識點之排序氣泡排序法,選擇排序

public class Demo2{     public static void main(String[] args){         //建立陣列arr         int[] arr = {1,9,5,7,3,2,6};         //輸出原陣列序列

常用排序氣泡排序選擇排序,插入排序,希爾排序,歸併排序,快速排序

#include <stdio.h> #define MAX 10 typedef int  ElementType; typedef ElementType ARR[MAX]; void swap(ARR arr,int i,int j) {     E

Java第一次作業規範化輸出二維陣列排序問題

2. (15分)某省居民電價分三個“階梯”:月用電量50度以內的,電價為0.538元/度;用電量在51度至200度之間的,電價為0.568元/度,用電量超過200度的,電價為0.638元/度。編寫程式,使用者從鍵盤輸入用電量,程式輸出使用者應繳納的電費。 (輸入輸出介面,迴圈)(格式化輸出)

演算法設計——成績排序氣泡排序

問題說明 輸入幾名同學的姓名何成績,對這些同學的成績進行排序,然後按照成績從大到小的順序進行排序,輸出對應的名次和姓名 程式碼實現 #include<iostream> // 輸入姓名時可用字串輸入,輸入字串標頭檔案表示 #include<string

簡單排序氣泡排序

溫故而知新,可以為師矣。 今天寫一篇關於排序演算法的部落格,理一理學習的思路。 首先 一想到排序演算法最簡單易懂的當然是氣泡排序了,現在給大家理一理氣泡排序的思路,氣泡排序的的基本思路是在相鄰的兩個數字之間比較,然後將比較小的放在前面,然後依次比較。

常見的幾種排序算法-插入選擇冒泡快排堆排等

最大和 字符串 父節點 重點 慢慢 選擇 arrays i++ 空間復雜度 排序是一個非常常見的應用場景,很多時候,我們需要根據自己需要排序的數據類型,來自定義排序算法,但是,在這裏,我們只介紹這些基礎排序算法,包括:插入排序、選擇排序、冒泡排序、快速排序(重點)、堆排序、

演算法DFS應用-拓撲排序

深度優先搜尋(DFS)演算法是最重要的圖遍歷演算法,基於DFS框架,可以匯出大量的圖演算法,圖的拓撲排序即為其中一個很典型的例子。 拓撲排序:給定一個有向圖,如何在保證“每個頂點都不會通過邊,指向其在此序列中的前驅頂點”這一前提下,將所有頂點排成一個線性序列。 例如: 在編寫教材時,

C++演算法選擇排序

#include <iostream> using namespace std; void myswap2(int &a, int &b) { int temp = b;

python 排序方式之冒泡,選擇,插入排序

class SortList(object): '''定義一個類方法,把多種排序方法整合起來''' def __init__(self,items=None): self.items=items def bubble_sort(self,li):

Java排序方法--List,數組,自定義繼承Comparable和Comparator

pri locale student ide abcdefg 接口 com main object (一)list和數組 ①List默認排序代碼: public static void main(String[] args) { List<String>

NOJ1002演算法實驗一分治演算法歸併排序

1002.歸併排序 時限:1000ms 記憶體限制:10000K  總時限:3000ms 描述 給定一個數列,用歸併排序演算法把它排成升序。 輸入 第一行是一個整數n(n不大於10000),表示要排序的數的個數; 下面一行是用空格隔開的n個整數。 輸出

經典演算法:希爾排序的實現

希爾排序我感覺並沒有什麼用 = =因為希爾排序事實上是對插入排序的一個複雜化,在插入排序的基礎上引入了一種分組機制,所以這種排序事實上是複雜了。 並且這種排序和插入排序的實現機制非常相似,只要稍微增加

經典演算法:烙餅排序

原理非常簡單,看視訊即可 給一個為排序的陣列,你只能再改對該陣列做如下操作:flip(arr, i): 將陣列arr[0...i]進行逆置。如何對該陣列進行排序? 這個問題在程式設計之美一書也有提及: 星期五的晚上,一幫同事在希格瑪大廈附近的“硬碟酒吧”多喝了幾杯。程式設

二叉排序樹(BST) 小講 理解 + 例題 更新ing ...

    很多時候會去忘記,你真正在乎的,是什麼、、、     set 就是用BST來維護集合的一個容器,書上根本沒講、、、、     定義:二叉排序樹(Binary Sort Tree)又稱二叉查詢樹(Binary Search Tree),亦稱二叉搜尋樹。 它或者是一棵空

圖解演算法排序演算法——歸併排序

0.什麼是歸併排序(Merge sort)? 是建立在歸併操作上的一種有效的排序演算法,效率為O(n log n)。1945年由約翰·馮·諾伊曼首次提出。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用,且各層分治遞迴可以同時進

圖解演算法排序演算法——堆排序

簡介 關於堆排序(HeapSort),堆這種資料結構比這種排序演算法更為有價值。 堆排序(Heapsort)是指利用堆積樹(堆)這種資料結構所設計的一種排序演算法,它是選擇排序的一種。可以利用陣列的特點快速定位指定索引的元素。堆分為大根堆和小根堆,是完

分治演算法歸併排序,快速排序和漢諾塔

1介紹 分治演算法已經是本人所寫的常用算法系列的第三個了,可能只會寫這一節,對比動態規劃與貪心演算法我們來認識一下分治演算法。 從思路上來看: (1)動態規劃:多階段過程轉化為一系列單階段問題,利用各階段之間的關係,逐個求解。每一個階段的最優解是基於前一個階段的最優解。

圖解演算法排序演算法——插入排序

插入排序(insertion sorting) 大體含義是這樣的,想我們在打撲克牌理牌時的思路一樣,來一張撲克牌做一次插入操作。 下面我們給出普通版和優化版的插入排序 public int [] insertionSort(int [] a