常见排序算法(迭代及递归)

归并排序(递归):

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
void MergeSort(int* arr,int left,int right,int* temp);
int main()
{
        int arr[]={44,3,38,5,47,15,36,26,27,2,46,4,19,50,48};
        int ii = sizeof(arr)/sizeof(int);
        int temp[ii];
        for(int i=0;i<ii;i++)
        cout<<arr[i]<<" ";
        cout<<endl;     
        MergeSort(arr,0,ii-1,temp);
        for(int i=0;i<ii;i++)
        cout<<temp[i]<<" ";
        cout<<endl;
}
void MergeSort(int* arr,int left,int right,int* temp)
{
        if(left>=right) return ;
        int mid = left+(right-left)/2;
        int i=left;int j = right;
        MergeSort(arr,i,mid,temp);
        MergeSort(arr,mid+1,j,temp);
        int ll = left;int jj = mid+1;
        int k = left;
        while(ll<=mid && jj<=right)
        {
                temp[k++] = arr[ll]<=arr[jj]?arr[ll++]:arr[jj++];
        }       
        while(ll<=mid) temp[k++] = arr[ll++];
        while(jj<=right) temp[k++] = arr[jj++];
        memcpy(arr+left,temp+left,(right-left+1)*sizeof(int));
}     

归并排序(迭代):

#include <iostream>
using namespace std;
// 归并排序(迭代 模板函数)
template<typename T>
void merge_sort(T arr[], int len)
{
  T* a = arr;
  T* b = new T[len];
  // seg:步长 每次循环增加一倍 1 2 4 8 16,直到超过数组长度 
  for(int seg = 1; seg < len; seg *=2)
  {
    // 比较 2*seg 个数的区间,再后移2*seg个数再比较,以此类推,直到超过数组
长度
    for(int start = 0; start < len; start += 2*seg)
    {
      // 一区间开始
      int low = start;
      // 一区间结束/二区间开始
      int mid = min(start + seg, len);
      // 二区间结束
      int high = min(start + 2*seg, len);
      // 合并数组的开始下标
      int k = start;
      // start1 <= 一区间 < end1(start2)
      int start1 = low, end1 = mid;
      // start2 <= 二区间 < end2
      int start2 = mid, end2 = high;
      // 一区间和二区间进行比较,谁小谁去合并数组,该区间下标+1,直到某一区
间比较完毕
      while(start1 < end1 && start2 < end2)
        b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
      // 若一区间未比较完毕,依次追加录入合并数组
      while(start1 < end1)
        b[k++] = a[start1++];
      // 若二区间未比较完毕,依次追加录入合并数组
      while(start2 < end2)
        b[k++] = a[start2++];
    }
    // 交换 a b,将未完美的合并数组再次按上述步骤合并,但步长加倍
    T* temp = a;
    a = b;
    b = temp;
  }

  // a指向的地址空间内存储的一直都是合并后的数据(除刚开始)
  // 所以如果a现在不指向arr[]的地址,那么a此时指向的是b被分配的空间地址
  // 而b现在指向的是arr[]的地址,但是b指向的空间需要被释放
  // 所以先将a(合并后的数据)转移到b(arr[]),然后再释放原始的b(也就是现在的a,所以b=a)
  if(a != arr)
  {
    for(int i = 0; i < len; i++)
      b[i] = a[i];
    b = a;
  }
  delete[] b;
}

int main()
{
  // 随意的数组
  int arr[] = {19, 15, 3, 5, 94, 74, 46, 6, 37, 28, 18, 7};

  // 获取数组长度
  int len = sizeof(arr) / sizeof(int);

  // 输出排序前的数组
  cout << "排序前的数组为:" << endl;
  for(int i=0;i<len;i++)
    cout << arr[i] << ' ';
  cout << endl;

  // 执行归并排序
  merge_sort(arr, len);

  // 输出排序后的数组
  cout << "排序后的数组为:" << endl;
  for(int i=0;i<len;i++)
    cout << arr[i] << ' ';
  cout << endl;

  return 0;
}

堆排序(迭代+递归):

#include<iostream>
#include<vector>
using namespace std;
void swap(int *a,int *b) {int temp =*b;*b = *a;*a = temp;}
void heapify(int* arr,int start,int end)//迭代版本
{
        int dad = start;int son = dad*2+1;
        while(son<=end)
        {
                if(son+1<=end && arr[son]<arr[son+1]) son++;
                if(arr[dad]>arr[son]) return ;
                swap(&arr[dad],&arr[son]);
                dad = son;
                son = dad*2+1;
        }
}
void heapify1(int *arr,int start,int end)//递归版本
{
  // 确定父节点和左子节点的数组下标。
  int dad=start;
  int son=dad*2+1;

  // 如果子节点的下标没有超出范围,循环继续。
  if (son>end ) return;

  // 先比较两個子节点大小,选择最大的。
  if ((son+1<=end) && (arr[son]<arr[son+1])) son++;

  // 如果父节点大于子节点代表调整完毕,直接跳出函数。
  if (arr[dad]>arr[son]) return;

  // 否则交换父子內容再继续子节点和孙节点比较。
  swap(&arr[dad],&arr[son]);

  heapify(arr,son,end);
}
void heapsort(int* arr,int len)
{
        for(int ii=len/2;ii>=0;ii--)
        {
                heapify(arr,ii,len);
        }
        for(int ii=len;ii>0;ii--)
        {
                swap(&arr[0],&arr[ii]);
                heapify(arr,0,ii-1);
        }
}
int main()
{
        int  arr[] = {44,3,38,5,47,15,36,26,27,2,46,4,19,50,48};
        int len = sizeof(arr)/sizeof(int);
        cout<<"排序前:"<<endl;
        for(int i=0;i<len;i++)
        cout<<arr[i]<<" ";
        heapsort(arr,len-1);
        cout<<"排序后:"<<endl;
        for(int i=0;i<len;i++)
        cout<<arr[i]<<" ";
        cout<<endl;
        return 0;
}

快速排序(递归):

#include <iostream>
#include <stdio.h>
using namespace std;
void quickSort(int* s,int left,int right);
int main()
{
        int s[] = {44,3,38,5,47,15,36,26,27,2,46,4,19,50,48};
        for(int i=0;i<15;i++)
        cout<<s[i]<<",";
        cout<<endl;
        quickSort(s,0,14);
        for(int yy=0;yy<15;yy++)
        {
                cout<<s[yy]<<",";
        }
        cout<<endl;
        return 0;
}

void quickSort(int* s,int left,int right)
{
        if(left>=right) return;
        int k = s[left];
        int i=left;int j=right;
        while(i<j)
        {
            while(i<j && s[j]>=k)
            {
                j--;
            }
            if(i<j) s[i++]=s[j];
            while(i<j && s[i]<=k)
            {
                i++;
            }
            if(i<j) s[j--] = s[i];
        }
        s[i] = k;
        quickSort(s,left,i);
        quickSort(s,i+1,right);
}

快读排序(迭代):

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <stack>
using namespace std;
int quickSort(int* arr, int l, int r);
void quickmiddle(int* arr, int l, int r) {
	stack<int> st;
	st.push(l);
	st.push(r);
	while (st.size()) {
		int j = st.top(); st.pop();
		int i = st.top(); st.pop();
		int middle = quickSort(arr, i, j);
		if (middle-1>i) {
			st.push(i);
			st.push(middle-1);
		}
		if (middle + 1 < j) {
			st.push(middle + 1);
			st.push(j);
		}
	}
}
int quickSort(int* arr, int l, int r) {
	int i = l, j = r;
	int k = arr[l];
	while (i < j) {
		while (i<j && arr[j]>k) {
			--j;
		}
		if (i < j) arr[i++] = arr[j];
		while (i < j && arr[i] <= k) {
			++i;
		}
		if (i < j) arr[j--] = arr[i];
	}
	arr[i] = k;
	return i;
}

int main() {

	int arr[] = { 8,33,5,1,3,0,43,2 };
	int len = sizeof(arr) / sizeof(int);
	quickmiddle(arr, 0, len-1);
	for (int i = 0; i < len; ++i) {
		cout << arr[i] << " ";
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值