排序 (一)

1.排序算法可以分为内部排序和外部排序。内部排序是数据记录在内存中进行排序。而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。

常见的内部排序算法有:选择排序、冒泡排序、插入排序、快速排序、希尔排序、归并排序、堆排序、基数排序等

2.各类排序的稳定性:可以通过观察数据是否有跳跃性移动来判断

稳定的排序算法:冒泡排序,插入排序,归并排序和基数排序

不稳定的排序算法:选择排序,快速排序,希尔排序和堆排序

3.各类排序的时间复杂度:

4.排序代码

#include<iostream>
#include<stack>
using namespace std;
#include<iostream>
using namespace std;


void Sort1(int arr[],int len)//冒泡排序
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - 1; j++)
		{
			if (arr[j] > arr[j+1])//两两排序
			{
				int tmp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = tmp;
			}
		}
	}
}
void Sort2(int arr[], int len)//选择排序
{
	for (int i = 0; i < len; i++)
	{
		//第一轮会将最小的元素放在最前面 第此后将剩余元素中最小元素依次放置在每次i的位置
		int min = i;
		for (int j = i; j < len; j++)//选择出最小元素下标
		{
			if (arr[j] < arr[i])
				min = j;
		}
		int tmp = arr[min];
		arr[min] = arr[i];
		arr[i] = tmp;
	}
}
/*
插入排序思路:
1. 从第一个元素开始,该元素可以认为已经被排序
2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5. 将新元素插入到该位置后
6. 重复步骤2~5*/
void InsertSort(vector<int>& v)//插入排序
{
    int len = v.size();
	for (int i = 1; i < len; ++i) {
		int temp = v[i];
        for(int j = i - 1; j >= 0; --j)
        {
            if(v[j] > temp)
            {
                v[j + 1] = v[j];
                v[j] = temp;
            }
            else
                break;
        }
	}
}
int Divide(int arr[], int left, int right)//分区函数
{
	int tmp = arr[left];
	while (left < right)
	{
		while (left<right&&arr[right]>tmp) right--;//最右边的数比标志大 right--
		if (left < right)         //right下标处数比标志小 将left下标处放arr[right]的值
		{
			arr[left] = arr[right];
			left++;
		}
		while (left < right&&arr[left] < tmp)  left++;//与上同理
		if (left < right)
		{
			arr[right] = arr[left];
			right--;
		}
		arr[left] = tmp;
		return left;//返回分割点下标
	}
}
void QuickSort(int arr[],int left,int right)//不断递归排序
{
	int index = Divide(arr,left,right);
	if (left < right)
	{
		QuickSort(arr,left,index-1);//左分区排序
		QuickSort(arr,index+1,right);//右分区排序
	}

}
void Sort3(int arr[],int len)//快排递归
{
	QuickSort(arr,0,len-1);
}
void Sort4(int arr[],int left,int right)//快排非递归
{
	stack<int> st;   //通过不断压栈出栈区间实现
	int index = Divide(arr,left,right);
	st.push(right);
	st.push(index+1);
	st.push(index-1);
	st.push(left);
	while (st.size() > 0)
	{
		left = st.top();
		st.pop();
		right = st.top();
		st.pop();
		int mid = Divide(arr,left,right);
		if (mid + 1 < right)//区间中的元素数不小于2
		{
			st.push(right);
			st.push(mid+1);
		}
		if (mid - 1 > left)//区间中的元素数不小于2
		{
			st.push(mid - 1);
			st.push(left);
		}
	}
}



void Merge(int array[], int left, int right, int middle)
{
	int left_len = middle - left;
	int right_len = right - middle - 1;
	int* left_array = new int[left_len];
	int* right_array = new int[right_len];
	int i, j, k;

	//单独摘出两个有序序列
	for (i = 0; i <= left_len; i++)
	{
		left_array[i] = array[i + left];
	}

	for (j = 0; j <= right_len; j++)
	{
		right_array[j] = array[j + middle + 1];
	}

	k = left;
	i = 0; j = 0;
	while (i <= left_len && j <= right_len)
	{
		if (left_array[i] < right_array[j])
			array[k++] = left_array[i++];
		else
			array[k++] = right_array[j++];
	}
	while (i <= left_len)
		array[k++] = left_array[i++];
	while (j <= right_len)
		array[k++] = right_array[j++];
}
void MergeSort2(int*arr, int left, int right)//归并递归
{
	if (arr == NULL || right + 1 <= 0)
	{
		return;
	}
	if (left < right)
	{
		int mid = (right + left) / 2;
		MergeSort2(arr, left, mid);
		MergeSort2(arr, mid + 1, right);
		Merge(arr, left, right, mid);
	}
}





void MergeNice(int* arr, int len, int num)//归并非递归
{
	int low1 = 0;
	int high1 = low1 + num - 1;
	int low2 = high1 + 1;
	int high2 = low2 + num - 1 < len ? low2 + num - 1 : len - 1;

	int* brr = new int[len];
	int i = 0;
	while (low1<len)
	{
		while (low1 <= high1&&low2 <= high2)
		{
			if (arr[low1] < arr[low2])
			{
				brr[i++] = arr[low1++];
			}
			else
			{
				brr[i++] = arr[low2++];
			}
		}
		while (low1 <= high1)
		{
			brr[i++] = arr[low1++];
		}
		while (low2 <= high2)
		{
			brr[i++] = arr[low2++];
		}

		low1 = high2 + 1;
		high1 = low1 + num - 1;
		low2 = high1 + 1;
		high2 = low2 + num - 1 < len ? low2 + num - 1 : len - 1;
	}
	for (i = 0; i < len; i++)
	{
		arr[i] = brr[i];
	}
}
void MergeSort1(int *arr, int len)
{
	if (arr == NULL || len <= 0)
	{
		return;
	}
	for (int i = 1; i < len; i *= 2)
	{
		MergeNice(arr, len, i);
	}
}


int main()
{
	int arr[] = {5,4,3,2,8};
	int len = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
	//Sort1(arr,len);
	//Sort2(arr, len);
	//InsertSort(arr,len);
	//Sort3(arr,len);
	//Sort4(arr,0,len-1);
	//MergeSort1(arr,len);
	//MergeSort2(arr,0,len-1);
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值