八大内存排序算法

类型一、选择排序

(1)冒泡排序:
a.每趟排序,最大沉底;
b.排列元素个数逐渐(从尾)减一,因为每趟排序,最后一位已确定;
c.每次冒泡序列:0 ~ i-1
TimeCost:O(N^2)
SpaceCost:O(N)

代码:

void BubbleSort(int[] nums){
	int i,j;

	for(i=nums.length; i>0; i--){
		for(j=0; j<i; j++){
			if(nums[j] > nums[j+1])
				swap(nums[j], nums[j+1]);
		}
	}
}

(2)快速排序(划分排序、基准位排序)

a. 思想:基准位排序,每趟划分找出基准位,基准位左边小于它,基准位右边大于它;

b. 递归操作
递归原子操作:分别划分基准位左边序列(left,k-1) 和基准位右边序列(k+1,right);
递归判定条件:最小划分为单个元素,基准位为单个元素,此时left == right,所以判定条件为left < right;

c. 复杂度分析
Time Complexity:共(logN)趟划分,每趟划分耗时(O(N)),共耗时O(NlogN),所以O(NlogN);
Space Complexity:递归栈深度为N, 所以O(N);

代码:

/*启动函数*/
void StartQuickSort(int[] nums){
	QuickSort(nums, 0, nums.length);
}

/*快排函数*/
void QuickSort(int[] nums, int left, int right){
	int k = 0;
	if(left < right){
		k = Partition(nums, left, right);
		QuickSort(nums, left, k-1);
		QuickSort(nums, k+1, right);
	}
}

/*划分函数, 返回基准元素*/
int Partition(int[] nums, int left, int right){
	int pivot = left;
	while(left < right){
		while(nums[left] < nums[k]) left++;

		while(nums[right] > nums[k]) right++;

		if(left < right)
			swap(nums[left], nums[right]);
	}
	swap(nums[pivot], nums[right]);

	return right;
}

类型二、选择排序

(3) 简单选择排序:
a.每趟从已知序列中找出最小值,与首元素交换;
b.排列元素个数逐渐(从头)减一,因为每趟排序,首位已确定;
c.每次选择序列:i ~ len;
TimeCost:O(N^2)
SpaceCost:O(N)

代码:

void SelectSort(int[] nums){
	int i,j,min;

	for(i = 0; i<nums.length; i++){
		for(j = i, j<nums.length;j++){
			min = nums[j];
			if(nums[j] < min)
				min = nums[j]
		}
		swap(num[i], min);
	}
}

(4)堆排序:
利用小顶堆,每次输出堆顶值(最小值);
TimeCost:O(NlogN)
SpaceCost:O(N)

类型三、插入排序

(5)直接插入排序:
a. 以首元素为有序序列,后面元素依次插入有序序列;
b. 每次插入序列:0 ~ i;
TimeCost:O(N^2)
SpaceCost:O(N)

代码:

void InsertSort(int[] nums){
	int i,j;

	for(i = 1; i<nums.length; i++){
		for(j = 0; j<i; j++){
			if(nums[j] > nums[j+1])
				swap(nums[j], nums[j+1]);
		}
	}
}

(6)希尔排序

类型四、合并排序

(7)合并排序
在这里插入图片描述

a. 思想:
先分裂,再合并;
合并两个有序序列,最小的有序序列为单个;

b. 递归操作
递归原子操作:合并(left, mid)和(mid+1, right)两个有序序列
递归判定条件:取决于原子操作,单个有序序列只有一个元素,left和right相等,即可返回,所以判定条件为 left < right;

c. 复杂度分析
Time Complexity:O(NlogN)
Space Complexity:O(N)

代码:

    int[] sort(int[] nums, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
            // 左边分裂
            sort(nums, low, mid);
            // 右边分裂
            sort(nums, mid + 1, high);
            // 左右归并
            merge(nums, low, mid, high);
        }
        return nums;
    }

    void merge(int[] nums, int low, int mid, int high) {
        int[] temp = new int[high - low + 1];
        int i = low;		// 左指针
        int j = mid + 1;	// 右指针
        int k = 0;

        // 把较小的数先移到新数组中
        while (i <= mid && j <= high) {
            if (nums[i] < nums[j]) {
                temp[k++] = nums[i++];
            } else {
                temp[k++] = nums[j++];
            }
        }

        // 把左边剩余的数移入数组
        while (i <= mid) {
            temp[k++] = nums[i++];
        }

        // 把右边边剩余的数移入数组
        while (j <= high) {
            temp[k++] = nums[j++];
        }

        // 把新数组中的数,覆盖部分nums数组
        for (int k2 = 0; k2 < temp.length; k2++) {
            nums[k2 + low] = temp[k2];
        }
    }

类型五、基数排序(桶排序)

(8)基数排序

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值