常见排序算法的实现------交换排序

交换排序:

交换排序的分类:

冒泡排序
快速排序
1.冒泡排序:

思想:从数组的末尾元素开始比较两个元素的大小,然后根据大小换位置,直到将最大或最小的元素排到数组的起始位置;
在这里插入图片描述
代码实现如下:

void Swap(int *left,int* right){
	in tmp=*left;
	*left=*right;
	*right=tmp;
}

void Bubblesort(int arr[],int size){
	for(int bound=0;bound<size;++bound){
		for(int cur=0;cur<size-1-bound;cur++){
			if(arr[cur]>arr[cur+1]){
				Swap(&arr[cur],&arr[cur+1});
			}
		}
	}
}

int main(){
	int array[]={9,5,2,4}
	int size=sizeof(arr)/sizeof(arr[0]);
    Bubblesort(array,size);
	return 0;
}

2.快速排序:

思路:三大步:

第一步:确定一个基准值;

找基准值的方法:
1.选边上;
2.随机法;
3.三数取中法:区间最左边,区间最右边,选值是中间一个数;

(第二种和第三种方法需要把值交换到边上)

第二步:做分割:遍历整个数组区间,比较每个数和基准值的大小关系,遍历结束后让比基准值小的放大它左边,比基准值大的放到它右边(左边比基准值小,右边比基准值大)

关于做分割的具体三种方法:
1.Hover法(左右指针法/左右下标法)

//对数组中的[low,hight]的区间进行分组,基准值是array[low]
int Partition(int array[],int low,int hight){
	int piove=array[low];
	int begin=low;
	int end=hight;
	//[begin,end]的区间是没被比较过的数;
	while(begin<end){
		while(begin<end && array[begin]<=piove){
			begin++;
		}
		while(begin<end && array[end]>=piove){
			end--;
		}
		//array[begin]比基准值大了,交换begin和end下标处的数据;
		Swap(array,begin,end);
	}
	  //low基准值;
      //[low+1,begin] 比基准值小;
      //[begin+1,high] 比基准值大;
      //把基准值和比他小的最后一个数进行交换;
      Swap(array,low,begin);
      return begin;
}
			

2.挖坑法:(通过来回填坑进行交换)

int Partition(int array[], int low, int high){
      int pivot = array[low]; //begin 是坑的下标;
      int begin = low;      //从基准值的位置开始,而不是low+1;
      int end = high;
      //(begin,end)的区间是没有被比较过的数据;
      while (begin < end){
           //如果基准值在左边,需要从右边开始走;
           while (begin<end && array[begin] <= pivot){
                 begin++;
           }
            //array[begin]比基准值大了,坑的下标是end;
            //array[end] = array[begin];
            //begin变为坑的下标;
           
           while (begin<end && array[end] >= pivot){
                 end--;
           }
           //array[end]比基准值小了,坑的下标就是begin;
           array[begin] = array[end];
           //end是坑的下标;
      }
      //low基准值;
      //[low+1,begin] 比基准值小;
      //[begin+1,high] 比基准值大;
      //最后把基准值填到最后一个坑;
      array[begin] = pivot;
      return begin;
}

3.前后指针法:

int Partition(int array[], int low, int high){
      int d = low + 1;
      int i = low + 1;
      int pivot = array[low];
      while (i <= high){
           if (array[i] < pivot){
                 Swap(array,d,i);
                 d++;
           }
           i++;
      }
      Swap(array, d - 1, low);
      return d - 1;
}


第三步:采用一个分治算法;按同样的方式,分别对同样两个小区间进行处理,直到分出来的小区间的长度个数 <= 1, 就可以停止;

快速排序算法的实现:
1.通过递归的方法进行查找:
int Partition(int array[],int low,int hight){
	int piove=array[low];
	int begin=low;
	int end=hight;
	while(begin<end){
		while(begin<end && array[begin]<=piove){
			begin++;
		}
		while(begin<end && array[end]>=poive){
			end--;
		}
		array[begin]=array[end];
	}
	array[begin]=piove;
	return begin;
}

void _QuickSort(int array[], int low, int high){
      if (low == high){     //区间内只剩一个数,有序,所以不需要排序;
           return;
      }
      if (low > high){
           return;             //区间内没有数,所以不需要排序;
      }
      
      //1.找基准值,选最左边,基准值得下标是low;
      //2.遍历整个区间,把小的放左边,大的放右边,返回基准值所在下标;
      int pivotIdx = Partition(array, low, high);
      
      //3.区间被分为三部分:
      //[low,pivotIdx-1]  小
      //[pivotIdx,pivotIdx]  有序
      //[pivotIdx+1,high]  大
      
      //4.分治算法,分别调用两个小区间;
      _QuickSort(array,low, pivotIdx - 1);
      _QuickSort(array,pivotIdx + 1, high);
      
      //直到区间长度为0,或区间长度为1,表示区间的数已经有序;
}

void QuickSort(int array[], int size){  
      _QuickSort(array, 0, size - 1);
}
2.非递归的快速排序:
#include <stack>
void QuickSortNoR(int array[], int size){
      std::stack <int> stack;
      stack.push(0);            //low
      stack.push(size - 1);     //high
      while (stack.empty()){
           int high = stack.top();
           stack.pop();
           int low = stack.pop();
           stack.pop();
           
           if (low >= high){
                 continue;
           }
           
           int pivotIdx = Partition(array, low, high);
           [low,pivotIdx-1]
           stack.push(low);
           stack.push(pivotIdx - 1);
           [pivotIdx+1,high]
           stack.push(pivotIdx + 1);
           stack.push(high);
      }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值