排序整理(交换,分配)

Edge插件默认位置在:
C:\Users\AppData\Local\Microsoft\Edge\User Data\Default\Extensions

交换

冒泡排序: O( n 2 n^{2} n2)

//	10个数从小到大排 
// 大数不断往后沉
  for(i=0;i<9;i++){        //趟数:10-1 
  	for(j=0;j<9-i;j++){   //每趟 在 [0,9-i]之间的元素进行比较, 大数不断下沉
  		if(a[j]>a[j+1]){
  			t=a[j];
  			a[j]=a[j+1];
  			a[j+1]=t;
		  }
	  }
  }

快速排序

void qSort(int a[] ,int left, int right){
	if(left<right){
	  	int temp=a[left];
  		int i=left,j=right;			// 初始化 i j 指向
  		while(i<j){
    		while(i<j&&a[j]>=temp)j--;		// 找 比 temp 小的元素, 找到之后 j 保持不动。将值给到 i 位置处。
		    a[i]=a[j];
		    while(i<j&&a[i]<=temp)i++;
		    a[j]=a[i];
  		}
  		a[i]=temp;
  		qSort(a,left,i-1);
  		qSort(a,i+1,right);
	}
}

选择排序: O( n 2 n^{2} n2)

//选择排序,从大到小排 
for(i=0;i<9;i++){
	k=i;
	for(j=i+1;j<10;j++){    //第一轮,找出10个中最大的 
		if(a[j]>a[k]){     //第二轮,找出后面9个中最大的 
			k=j;          //第三轮, ... 
		}
	}
	if(k!=i){
		t=a[i];a[i]=a[k];a[k]=t;
	}
} 

直接插入排序: O( n 2 n^{2} n2)

void Insert_sort(ElementType A[],int n){
	int i,j;
	ElementType Temp;
	for(i=1;i<n;i++){	 // 从 序号为1 的元素 开始,和前面的元素 进行比较
		Temp=A[i];
		for(j=i;j>0&&A[j-1]>Temp;j--)	// 与前边的元素 进行比较 并后移 
			A[j]=A[j-1];
		A[j]=Temp;
	}
}

希尔排序

改进的插入排序,减少了元素的比较,交换次数

void Insert_sort(ElementType A[],int n){
	int i,j,gap;
	ElementType Temp;
	for(gap=n/2;gap>0;gap/=2){		// 增量序列   递减至 1 
//	
		for(i=gap;i<n;i++){	//  从 序号 为 gap 的元素开始
			Temp=A[i];
			for(j=i;j>gap-1&&A[j-gap]>Temp;j-=gap){	  //  和 前面 距离 差 gap 的元素 进行比较
				A[j]=A[j-gap];
			}
			A[j]=Temp;
		}
//
	}
}

堆排序

void Swap( ElementType *a, ElementType *b ){
     ElementType t = *a; *a = *b; *b = t;
}
 
void PercDown( ElementType A[], int p, int N )
{ 	// 由于 数据从0开始存储 ,所以左孩子是 2*i+1 , 右孩子是 2*i+2
  /* 将N个元素的数组中以A[p]为根的子堆调整为最大堆 */
    int Parent, Child;
    ElementType X;

    X = A[p]; /* 取出根结点存放的值 */
    for( Parent=p; (Parent*2+1)<N; Parent=Child ) {
        Child = Parent * 2 + 1;
        if( (Child!=N-1) && (A[Child]<A[Child+1]) )
            Child++;  /* Child指向左右子结点的较大者 */
        if( X >= A[Child] ) break; /* 找到了合适位置 */
        else  /* 下滤X */
            A[Parent] = A[Child];
    }
    A[Parent] = X;
}

void HeapSort( ElementType A[], int N ) 
{ /* 堆排序 */
     int i;
      
     for ( i=N/2-1; i>=0; i-- )/* 建立最大堆 */
         PercDown( A, i, N );
     
     for ( i=N-1; i>0; i-- ) {
         /* 删除最大堆顶 */				// 把最大的数不断移到后面
         Swap( &A[0], &A[i] ); 
         PercDown( A, 0, i );
     }
}

分配

不需要进行待排序元素之间的比较,但需要事先知道这些元素的一些情况。

桶排序

待排元素的值都位于某个较小的区间范围之内 [0,max)
将相同值的元素 都放在同一个桶里。

void bucket_sort(int arr[],int n,int max){
    int *count=new int[max];
    
    int *temp=new int[n];   // 临时数组
    for(int i=0;i<n;i++){
        temp[i]=arr[i];
    }
    for(int i=0;i<max;i++){
        count[i]=0;         // 初始为0
    }
    for(int i=0;i<n;i++){
        count[arr[i]]++;    // 统计 arr 中每个元素出现的次数
    }
    for(int i=1;i<max;i++){
        count[i]=count[i-1]+count[i];   // 统计 该元素前面有多少个元素,包括自己
    }
    for(int i=n-1;i>=0;i--){			// 从尾部开始,保证稳定性(例如 有两个相同的数,排完之后,仍可以保证他们之间的相对顺序和之前一样)
        arr[--count[temp[i]]]=temp[i];
    }
}

在这里插入图片描述
也可以挂起来

const int N=10;
typedef struct nid{
    int data;
    struct nid *next;
}node;
typedef struct nid * bucket[N];
bucket a; // 桶里的元素是指向 struct nid 的指针

// 值一样的元素挂到一串下

在这里插入图片描述
总之就是,将值一样的元素归结到一块儿,而后串在一起,没有发生待排元素之间的比较。

基数排序

假设有N=10个整数,每个整数的值在 0~999 之间,如果用桶排序,就要建一个大小为1000的桶。
对于这样的情况,考虑分为个位,十位,百位依次进行桶排。

void Radix_sort(int arr[],int n,int max,int d){
// n 是数组长度,max是桶的大小,d是待排元素有几个关键码(例如:637,有个位,十位,百位,三个关键码)
// 对于 区间在[0,999] 的一组数据, d就取3。每一位的数都在[0,9]范围内, max就取10
    int *count=new int[max];
    int *temp=new int [n];
    int Radix=1;            // 用于取 arr[i]的某一位

    for(int i=0;i<d;i++){// 进行 d 轮
        for(int k=0;k<n;k++){
            temp[k]=arr[k];     //临时数组
        }
        for(int j=0;j<max;j++){
            count[j]=0;         // 初始化
        }
        for(int k=0;k<n;k++){
            count[(arr[k]/Radix)%max]++;        // 依据某一位上的数字进行统计
        }
        for(int j=1;j<max;j++){
            count[j]=count[j-1]+count[j];       // 做一个累加序列
        }
        for(int k=n-1;k>=0;k--){
            arr[--count[(temp[k]/Radix)%max]]=temp[k];
        }
        Radix*=max;
    }

}

为什么要依次?


对于 (35,43,37,33,36),如果直接按十位进行排序,无论是
从尾部开始:得到 (35,37,33,36,43)
从头部开始:得到 (36,33,37,35,43)
可见,对于十位数值一样的一组数来说,他们的内部依然不是有序的,结果都是不对的。
而如果先进行个位的排序,得到:尾部开始(43,33,35,36,37)/ 头部开始(33,43,35,36,37),此时,个位就是有序的
然后再进行按十位的排序(从尾部开始),得到(33,35,36,37,43)

从尾部开始有何意义?


排完序之后,相对顺序不会改变。
对于上面的个位排序,之前,43本就是在33前面,从尾部开始可以保证这点不会改变
对于上面的十位排序,之前,个位排序之后得到的(33,35,36,37),如果十位排序是从尾部开始,就可以保证这个相对顺序。否则,如果是从头部开始,就会得到(37,36,35,33)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值