希尔排序+堆排序简介与代码实现

希尔排序

简介

希尔排序是第一批冲破二次时间屏障的第一批算法,其使用比较相距一定间隔的元素来工作,各趟比较的距离随着算法的进行而减少,知道比较相邻距离的最后一趟排序为止。因此也叫做最小增量排序

希尔排序的最重要部分在于增量序列,即使用的距离序列 h 1 , h 2 , ⋯   , h n h_1,h_2,\cdots,h_n h1,h2,,hn,其中只要 h 1 = 1 h_1=1 h1=1则希尔排序有效,但是增量序列的选择却是决定希尔排序时间复杂度的决定性因素。
希尔排序生效的还有一个重要前提是“ h k h_k hk排序性”不变,此时后一次排序不会打乱前一次的排序结果。

序列选择

1.Shell序列

Shell序列指的是 h t = [ N / 2 ] h_t=[N/2] ht=[N/2] h k = [ h k + 1 / 2 ] h_k=[h_{k+1}/2] hk=[hk+1/2]的序列,使用该代码的希尔排序代码如下:

void sort(long long num[],int N){
	int i=N/2;
	while(i>=1){
		for(int j=0;j<i;j++){
			for(int k=j;k<N;k+=i){
				for(int m=k;m>j;m-=i){
					if(num[m]<num[m-i]){
						long long temp=num[m];
						num[m]=num[m-i];
						num[m-i]=temp;
					}
					else
						break;
				}
			}
		}
		i/=2;
	}
}

其最坏情形运行时间复杂度为 Θ ( N 2 ) \Theta(N^2) Θ(N2),只要令 N N N为2的幂,并且使得当 h = 2 h=2 h=2时的两条序列都为单调序列但不相交,例如

1,9,2,10,3,11,4,12,...

此时,除了 h = 1 h=1 h=1以外的增量序列均不会对其排序,浪费大量时间,具体证明这里不再赘述。

2.Hibbard序列
void sort(long long num[],int N){
	int i=1;
	while(i<N){
	    i=2*i;
	}
	i=i/2-1;
	while(i>=1){
		for(int j=0;j<i;j++){
			for(int k=j;k<N;k+=i){
				for(int m=k;m>j;m-=i){
					if(num[m]<num[m-i]){
						long long temp=num[m];
						num[m]=num[m-i];
						num[m-i]=temp;
					}
					else
						break;
				}
			}
		}
		i=(i+1)/2-1;
	}
}

Hibbard序列使用的是形如 1 , 3 , 7 , . . . , 2 k − 1 1,3,7,...,2^k-1 1,3,7,...,2k1的增量序列,其最坏复杂度为 O ( N 3 2 ) O(N^{\frac{3}{2}}) O(N23),证明不再赘述。

堆排序

堆排序是将优先队列用于排序的一种方法,简单来说,只要先对数组进行建堆操作建立最大堆,然后按顺序Delete Max即可。如果我们用一个新的数组去存取Delete得到的最大值,会导致其空间复杂度会达到 O ( N ) O(N) O(N)。为了降低空间复杂度,我们会将堆的堆首元素与堆尾元素交换位置,然后使堆的大小减小一后调整堆为最大堆。
实现代码如下:

void percdown(long long a[],int i,int N){
    while(i<N){
        if(2*i+2<N){
            if(a[2*i+2]>a[2*i+1])
                if(a[2*i+2]>a[i]){
                    long long temp=a[i];
                    a[i]=a[2*i+2];
                    a[2*i+2]=temp;
                    i=2*i+2;
                }
                else
                    break;//break容易被忘记
            else
                if(a[2*i+1]>a[i]){
                    long long temp=a[i];
                    a[i]=a[2*i+1];
                    a[2*i+1]=temp;
                    i=2*i+1;
                }
                else
                    break;
        }
        else if(2*i+1<N){
            if(a[2*i+1]>a[i]){
                long long temp=a[i];
                a[i]=a[2*i+1];
                a[2*i+1]=temp;
                i=2*i+1;
            }
            else
                break;
        }
        else
        break;
    }
}
void sort(long long num[],int N){
    for(int i=N-1;i>=0;i--){
        percdown(num,i,N);
    }
    for(int i=0;i<N;i++){
        long long temp=num[0];
        num[0]=num[N-1-i];
        num[N-1-i]=temp;
        percdown(num,0,N-1-i);
    }
}

P1177【模板】快速排序

题目描述

利用快速排序算法将读入的 N N N 个数从小到大排序后输出。

快速排序是信息学竞赛的必备算法之一。对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成。(C++ 选手请不要试图使用 STL,虽然你可以使用 sort 一遍过,但是你并没有掌握快速排序算法的精髓。)

输入格式

1 1 1 行为一个正整数 N N N,第 2 2 2 行包含 N N N 个空格隔开的正整数 a i a_i ai,为你需要进行排序的数,数据保证了 a i a_i ai 不超过 1 0 9 10^9 109

输出格式

将给定的 N N N 个数从小到大输出,数之间空格隔开,行末换行且无空格。

样例 #1

样例输入 #1

5
4 2 4 5 1

样例输出 #1

1 2 4 4 5

提示

对于 20 % 20\% 20% 的数据,有 N ≤ 1 0 3 N\leq 10^3 N103

对于 100 % 100\% 100% 的数据,有 N ≤ 1 0 5 N\leq 10^5 N105

AC代码如下

希尔排序

#include <stdio.h>
long long p[1000001];
void sort(long long num[],int N){
	int i=N/2;
	while(i>=1){
		for(int j=0;j<i;j++){
			for(int k=j;k<N;k+=i){
				for(int m=k;m>j;m-=i){
					if(num[m]<num[m-i]){
						long long temp=num[m];
						num[m]=num[m-i];
						num[m-i]=temp;
					}
					else
						break;
				}
			}
		}
		i/=2;
	}
}

int main()
{
 int n;
 scanf("%d",&n);
 for (int i = 0;i < n;i++)
 scanf("%lld",&p[i]);
 sort(p,n);
 for (int i = 0;i < n;i++)
 printf("%lld ",p[i]);
 return 0;
}

堆排序

#include <stdio.h>
long long p[1000001];
void percdown(long long a[],int i,int N){
    while(i<N){
        if(2*i+2<N){
            if(a[2*i+2]>a[2*i+1])
                if(a[2*i+2]>a[i]){
                    long long temp=a[i];
                    a[i]=a[2*i+2];
                    a[2*i+2]=temp;
                    i=2*i+2;
                }
                else
                    break;
            else
                if(a[2*i+1]>a[i]){
                    long long temp=a[i];
                    a[i]=a[2*i+1];
                    a[2*i+1]=temp;
                    i=2*i+1;
                }
                else
                    break;
        }
        else if(2*i+1<N){
            if(a[2*i+1]>a[i]){
                long long temp=a[i];
                a[i]=a[2*i+1];
                a[2*i+1]=temp;
                i=2*i+1;
            }
            else
                break;
        }
        else
        break;
    }
}
void sort(long long num[],int N){
    for(int i=N-1;i>=0;i--){
        percdown(num,i,N);
    }
    for(int i=0;i<N;i++){
        long long temp=num[0];
        num[0]=num[N-1-i];
        num[N-1-i]=temp;
        percdown(num,0,N-1-i);
    }
}

int main()
{
 int n;
 scanf("%d",&n);
 for (int i = 0;i < n;i++)
 scanf("%lld",&p[i]);
 sort(p,n);
 for (int i = 0;i < n;i++)
 printf("%lld ",p[i]);
 return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
希尔排序: ```python def shell_sort(arr): n = len(arr) gap = n // 2 while gap > 0: for i in range(gap, n): temp = arr[i] j = i while j >= gap and arr[j-gap] > temp: arr[j] = arr[j-gap] j -= gap arr[j] = temp gap //= 2 return arr ``` 快速排序: ```python def quick_sort(arr): if len(arr) <= 1: return arr pivot = arr[len(arr) // 2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort(left) + middle + quick_sort(right) ``` 归并排序: ```python def merge_sort(arr): if len(arr) <= 1: return arr mid = len(arr) // 2 left = merge_sort(arr[:mid]) right = merge_sort(arr[mid:]) return merge(left, right) def merge(left, right): result = [] i, j = 0, 0 while i < len(left) and j < len(right): if left[i] < right[j]: result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 result += left[i:] result += right[j:] return result ``` 堆排序: ```python def heapify(arr, n, i): largest = i l = 2 * i + 1 r = 2 * i + 2 if l < n and arr[i] < arr[l]: largest = l if r < n and arr[largest] < arr[r]: largest = r if largest != i: arr[i],arr[largest] = arr[largest],arr[i] heapify(arr, n, largest) def heap_sort(arr): n = len(arr) for i in range(n//2 - 1, -1, -1): heapify(arr, n, i) for i in range(n-1, 0, -1): arr[i], arr[0] = arr[0], arr[i] heapify(arr, i, 0) return arr ``` 计数排序: ```python def counting_sort(arr): max_value = max(arr) counts = [0] * (max_value + 1) result = [0] * len(arr) for x in arr: counts[x] += 1 for i in range(1, max_value + 1): counts[i] += counts[i-1] for i in range(len(arr)): result[counts[arr[i]] - 1] = arr[i] counts[arr[i]] -= 1 return result ``` 桶排序: ```python def bucket_sort(arr): max_value = max(arr) bucket_size = max_value // 10 num_buckets = max_value // bucket_size + 1 buckets = [[] for _ in range(num_buckets)] for x in arr: buckets[x // bucket_size].append(x) result = [] for bucket in buckets: result.extend(sorted(bucket)) return result ``` 基数排序: ```python def radix_sort(arr): max_value = max(arr) digit_count = len(str(max_value)) for digit in range(digit_count): buckets = [[] for _ in range(10)] for x in arr: bucket_index = (x // (10 ** digit)) % 10 buckets[bucket_index].append(x) arr = [] for bucket in buckets: arr.extend(bucket) return arr ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值