排序算法之三種基礎排序算法(冒泡、選擇、直接插入)

目錄

冒泡排序

選擇排序

直接插入排序


注:以下排序均默認爲升序排序。

冒泡排序

一、基本思想:

        從前往後,依次比較相鄰的兩個數,把較大的數放到後面;一次循環後,可以在當前最末尾位置得到一個當次循環的最大值。

  • 時間複雜度:O(n²)
  • 空間複雜度:O(1) 
  • 排序穩定程度 :穩定
  • 缺點:傳統的冒泡排序中每一趟排序只能找到一個最大值或最小值,效率低。

二、代碼實現:

-----------------------------------C#------------------------------------------------
#include<stdio.h>

void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
void Bubble(int arr[], int size)
{
	if (size <= 1)
		return;
	int ret;

	//依次將最大的數放置到數組末尾,將第二大的數放到倒數第二位...
	for (int i = 0; i < size - 1; ++i)
	{
		ret = 1;

		//從前往後,比較相鄰兩個數,把大的放在後邊.之前已放置成功的可以不再參與比較
		for (int j = 0; j < size - 1 - i; ++j)
		{
			if (arr[j] > arr[j + 1])
			{
				Swap(&arr[j], &arr[j + 1]);
				ret = 0;
			}
		}

        //冒泡每次都會比較相鄰兩個數並交換次序不對的組,若一次循環後,都沒進行交換,則已經完成排序
		if (ret)
			break;
	}
}

//test.c
int main()
{
	int arr[] = { 3,4,5,1,2};
	int size = sizeof(arr) / sizeof(arr[0]);
	Bubble(arr, size);
	for (int i = 0; i < size; ++i)
		printf("%d", arr[i]);
	system("pause");
	return 0;
}
-------------------------------------C++---------------------------------------------
#include<vector>
#include<iostream>
using namespace std;
class Bubble
{
public:
	vector<int> sort(vector<int> arr)
	{
		vector<int> ret;
		if (arr.size() <= 1)
			return ret;
		int changed;//標識位
		
		//依次將最大的數放置到數組末尾,將第二大的數放到倒數第二位...
		for (int i = 0; i < arr.size()-1; i++)
		{
			changed = 1;

			//從前往後,比較相鄰兩個數,把大的放在後邊.之前已放置成功的可以不再參與比較
			for (int j = 0; j < arr.size() - 1 - i; j++)
			{
				if (arr[j] > arr[j + 1]) 
				{
					int temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
					//arr=swap(arr,j,j+1);
					changed = 0;
				}
			}

			//冒泡每次都會比較相鄰兩個數並交換次序不對的組,若一次循環後,都沒進行交換,則已經完成排序
			if (changed)
				break;
		}
		ret = arr;
		return ret;
	}

	/*
	vector<int> swap(vector<int> arr, int a, int b)
	{
		vector<int> ret;
		int temp = arr[a];
		arr[a] = arr[b];
		arr[b] = temp;
		ret = arr;
		return ret;
	}
	*/
};

//test.c
int main()
{
	vector<int> array{ 3, 4, 5, 1, 2 };
	vector<int>ret;
	Bubble b;
	ret=b.sort(array);
	for (int i = 0;i<ret.size();++i)
	{
		cout << ret[i];
	}
	cout << endl;
	system("pause");
	return 0;
}

 

選擇排序

一、基本思想:

        首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小元素,然後放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

  • 時間複雜度 :O(n²)
  • 空間複雜度 :O(1)
  • 排序穩定程度 :不穩定
  • 適用場景:數據規模越小越好

二、代碼實現:

void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
void SelectSort(int arr[], int size)
{
	if (size <= 1)
		return;
	int min, ret;
	for (int i = 0; i < size - 1; ++i)
	{
		min = i;
		for (int j = i + 1; j < size; ++j)
		{
			if (arr[min] > arr[j])
				min = j;//找出當前最小元素的位置
		}
		Swap(&arr[min], &arr[i]);
	}
}

//test.c
int main()
{
	int arr[] = { 3,4,5,1,2};
	int size = sizeof(arr) / sizeof(arr[0]);
	SelectSort(arr, size);
	for (int i = 0; i < size; ++i)
		printf("%d", arr[i]);
	system("pause");
	return 0;
}

直接插入排序

一、基本思想:

        通過構建有序序列,對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。也就是說:從第二個元素開始,將當前元素插入到前面對應位置,使當前元素i和之前元素形成有序數組。

  • 時間複雜度:O(n²) 
  • 空間複雜度:O(1)
  • 排序穩定程度:穩定 
  • 適用場景:數據量小,元素接近有序。(儘可能少搬移元素)

二、代碼實現:

void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

void InsertSort(int arr[], int size)
{
	if (size <= 1) {
		return;
	}
	int pos;
	for (int i = 1; i < size; ++i) 
	{ 
		pos = i;
		while (pos != 0 && arr[pos] < arr[pos - 1])
		{
			Swap(&arr[pos], &arr[pos - 1]);
			pos--;
		}
	}
}

//test.c
int main()
{
	int arr[] = {3,4,5,1,2};
	int size = sizeof(arr) / sizeof(arr[0]);
	InsertSort(arr, size);
	for (int i = 0; i < size; ++i)
		printf("%d", arr[i]);
	system("pause");
	return 0;
}

 

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