数据结构C语言版清华大学严蔚敏(学习笔记总结7)——排序全代码:冒泡排序、直接插入排序、折半排序、希尔插入排序、选择排序、堆排序、归并排序、快速排序、基数排序【另附理解笔记】

数据结构C语言版清华大学严蔚敏(学习笔记总结6)——查找全代码:二分查找、折半查找、分块查找、哈希查找、哈希表、平衡二叉树(另附学习笔记)_玛卡巴卡的博客-CSDN博客

排序算法比较表格

排序算法    平均时间复杂度    最坏时间复杂度    空间复杂度     是否稳定
冒泡排序     O(n2)                 O(n2)                O(1)          是
选择排序     O(n2)                 O(n2)               O(1)         不是
直接插入排序 O(n2)              O(n2)               O(1)           是
归并排序 O(nlogn)                     O  (nlogn)             O(n)            是
快速排序 O(nlogn)                     O(n2)                O(logn)      不是
堆排序 O(nlogn)                         O(nlogn)                O(1)          不是
希尔排序 O(nlogn)                      O(ns)                 O(1)         不是
计数排序 O(n+k)                        O(n+k)                    O(n+k)            是
基数排序 O(N∗M)                        O(N∗M)                 O(M)                是
 

 1.冒泡排序

//冒泡
void bubble_sort(int arr[],size_t n){
	size_t i,j;
	for(i=1;i<n-1;i++){
		bool hasSwap = false;
		for(j=1;j<=n-i;j++){
			if(arr[j-1]>arr[j]){
				swap(&arr[j-1],&arr[j]);		
				hasSwap = true;
			}
		}
		if(!hasSwap){
			break;	
		}
	}
}

 2.直接插入排序

void insert_sort(int arr[],size_t n){
     int i,j;
     for(i=1;i<n;i++){
         int key = arr[i];
         for(j=i-1;j>=0 && arr[j]>key;j--){
             arr[j+1] = arr[j];
         }
         arr[j+1] = key;
     }
}

 3.折半插入排序

void bin_insert_sort(int arr[],size_t n){
	int i,j;
	for(i=1;i<n;i++){//arr[i]插入到[0,i-1]这个有序数组中
		int key = arr[i];
		int left = 0;
		int right = i-1;
		while(left <= right){
			int mid = (left+right)/2;
			if(key<arr[mid]){
				right = mid-1;
			}else{
				left = mid+1;	
			}
		}
		for(j=i-1;j>=left;j--){
			arr[j+1] = arr[j];	
		}
		arr[left] = key;
	}	

 4.希尔插入排序

//希尔排序
void shell_sort(int arr[],size_t n){
	size_t step;
	//分组
	for(step = n/2;step > 0; step = step/2){//step步长
		size_t i;
		//除了每组第一个元素以外 组内每个元素相隔step
		//对于后面所有的元素都要进行组内插入排序
		for(i=step;i<n;i++){//arr[0] arr[step-1]每个小组的第一个元素
			int j;
			int key = arr[i];
			for(j=i-step;j>=0 && arr[j]>key;j=j-step){//和组内元素比较
				arr[j+step] = arr[j];	
			}
			arr[j+step] = key;
		}
	}
}

 5.选择排序

void choice_sort(int arr[],size_t n){
     size_t i,j;
     for(i=0;i<n;i++){
          size_t m=0 ;
          for(j=1;j<n-i;j++){
              if(arr[j]>arr[m]){
                  m = j;
              }
          }
          if(n-i-1 != m){
              swap(&arr[n-1-i],&arr[m]);
          }
     }
}

 6.堆排序

void reheap(int arr[],size_t index,size_t n){
	size_t child = 2*index+1;
	int key = arr[index];
	while(child < n){
		if(child+1 < n && arr[child]< arr[child+1]){
			++child;
		}
		if(key<arr[child]){
			arr[index]=arr[child];
		}else{
			break;
		}
		index =child;
		child = index*2+1;
	}
	arr[index]=key;
}

void heap_sort(int arr[],size_t n){
	int i;
	for(i = 0;i<=n/2;i++){
		reheap(arr,i,n);
	}
	for(i = 0;i < n-1;i++){
		swap(&arr[0],&arr[i]);
		reheap(arr,n-1,i);
	}
}

void max_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;
        else  //否则交换父子内容再继续子节点和孙节点比较
        {
            swap(&arr[dad], &arr[son]);
            dad = son;
            son = dad * 2 + 1;
        }
    }
}
 
void heap_sort1(int arr[], int len) 
{
    int i;
    //初始化,i从最後一个父节点开始调整
    for (i = len / 2 - 1; i >= 0; i--)
        max_heapify(arr, i, len - 1);
    //先将第一个元素和已排好元素前一位做交换,再重新调整,直到排序完毕
    for (i = len - 1; i > 0; i--) 
    {
        swap(&arr[0], &arr[i]);
        max_heapify(arr, 0, i - 1);
    }
}

7. 归并排序

oid mergeArr(int arr[],size_t n){
	if(n<=1){
		return ;
	}
	int mid = n/2;
	int len =mid;
	int *prr = malloc(sizeof(int)*len);
	size_t i;
	for(i=0;i<len;i++){
		prr[i] = arr[i];
	}
	size_t j,k;
	i=0;
	j=mid;
	k=0;
	while(i<len && j<n){
		if(prr[i]<arr[j]){
			arr[k++]=prr[i++];
		}else{
			arr[k++]=arr[j++];
		}
	}
	while(i<len){
		arr[k++]=prr[i++];
	}
	free(prr);
}

void merge_sort(int arr[],size_t n){
	if(n<=1){
		return ;
	}
	int mid =n/2;
	merge_sort(arr,mid);
	merge_sort(arr+mid,n-mid);
	mergeArr(arr,n);

 8.快速排序

void quick(int arr[],int left,int right){
	if(left >= right)
		return;
	int i=left,j=right;
	int key = arr[i];
	while(i<j){
		while(i<j&&arr[j]>=key){
			--j;	
		}	
		arr[i] = arr[j];
		while(i<j&&arr[i]<=key){
			++i;	
		}
		arr[j] = arr[i];
	}
	arr[i] = key;
	if(i-1-left+1>1)
		quick(arr,left,i-1);
	if(right-(i+1)+1>1)
void quick_sort(int arr[],size_t n){
	if(n<=1){
		return;
	}
	size_t i=0,j=n-1;
	int key =arr[i];
	while(i<j){
		while(i<j && arr[j]>=key){
			--j;
		}
		arr[i] = arr[j];
		while(i<j && arr[i]<=key){
			++i;
		}
		arr[j] = arr[i];
	}
	arr[i] = key;
	if(i>1)
		quick_sort(arr,i);
	if(n-i-1>1)
		quick_sort(arr+i+1,n-i-1);
}

 9.基数排序

void base_sort(int arr[],size_t n){
	Bucket bucket[10] = {};
	int max = arr[0];
	size_t i;
	for(i=0;i<n;i++){
		if(max < arr[i]){
			max = arr[i];	
		}	
	}
	int div = 1;
	size_t j=0,k=0;
	do{
		for(i=0;i<n;i++){
			int n = arr[i]/div%10;
			bucket[n].vect[bucket[n].cnt++] = arr[i];
		}
		k=0;
		for(i=0;i<10;i++){
			for(j=0;j<bucket[i].cnt;j++){
				arr[k++] = bucket[i].vect[j];		
			}
			bucket[i].cnt = 0;
		}
		div = div*10;
		max = max/10;
	}while(max!=0);
}

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玛卡巴卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值