第五部分 排序算法综合介绍

目录

一、插入排序

     1、直接插入排序

     2、二分插入排序

     3、希尔排序

二、交换排序

    1、冒泡排序

     2、快速排序

三、选择排序

     1、简单选择排序

      2、堆排序

四、归并排序

五、编程题


排序算法平均时间复杂度空间复杂度稳定性备注
直接插入排序O(n^2)O(1)1小规模数据
冒泡排序O(n^2)O(1)1小规模数据
简单选择排序O(n^2)O(1)0小规模数据
希尔排序O(log_2{n})O(1)0中等大小规模数据
快速排序O(log_2{n})O(logn)0n 很大时,且有序程度高时
堆排序O(log_2{n})O(1)0n 很大时,且有序程度低时
归并排序O(log_2{n})O(n)1n 比较小时选取
基数排序O(log_2{RB})O(log_2{RB})1R为0-9,B为基数(个十百)
计数排序(桶排序)O(n)O(n)0范围比较小

一、插入排序

      从无序区中选取第一个元素,按关键字大小,插入有序区适当位置。

     1、直接插入排序

      将无序区中的元素,通过顺序查找,依次和有序区的元素进行比较,并插入适当位置。

      Java 版本

	public static int[] InsertSort(int[] nums) {
		
		for(int i=1; i<nums.length; i++) {
			
			int temp = nums[i], j = 0;
			for(j=i; temp < nums[j-1] && j>0; j--)
				nums[j] = nums[j-1];
			
			nums[j] = temp;
		}
		return nums;
	}

      Python 版本 

def sortArray(self, nums):

    for i in range(1, len(nums)):
        temp = nums[i]
        index = i
        for j in range(i, 0, -1):
            if temp < nums[j-1]:
                nums[j] = nums[j-1]
                index = j - 1
        nums[index] = temp
    return nums

     2、二分插入排序

      插入的位置,采用二分查找确定。

      Java 版本

	public static int[] BinaryInsertSort(int[] nums) {
		
		for(int i=1; i<nums.length; i++) {
			
			int temp = nums[i], j = 0;
			int left=0, right=i-1;
			
	        while(left <= right){
	        	
	            int mid=(left+right)/2;
	            if (temp > nums[mid])
	                left = mid+1;
	            else
	            	right = mid-1;
	        }
	        
			for(j=i; j>left; j--) 
				nums[j] = nums[j-1];
			
			nums[j] = temp;			
		}
		return nums;
	}

      Python 版本 

def function(nums):
    for i in range(1, len(nums)):

        temp = nums[i]
        index = i
        low = 0
        high = i-1

        while low <= high:
            mid = int((low + high) / 2)

            if nums[mid] < temp:
                low = mid + 1
            else:
                high = mid - 1

        for j in range(i, low, -1):
            nums[j] = nums[j - 1]
            index = j - 1
        nums[index] = temp

     3、希尔排序

      将代拍数组分成若干小组,间隔为步长 d 的元素在同一组,每个小组内部进行直接插入排序。逐步减少步长,重复,直至步长为1,并且数组有序。

	public static int[] sort(int[] nums){
		
		int n = nums.length;
		for(int gap=n/2; gap>0; gap = gap/2){
			
			for(int j = gap; j < n; j++){
				
				for(int i=j; i >= gap && nums[i-gap] > nums[i]; i -= gap){
					
					int temp = nums[i-gap];
					nums[i-gap] = nums[i];
					nums[i] = temp;
				}
			}
		}
		return nums;
	}

二、交换排序

    1、冒泡排序

      将待排数组从后往前两两比较相邻元素,逆序交换,直到数组有序。

      Java 版本

	public static int[] BubbleSort(int[] nums) {
		
		for(int i=0; i<nums.length; i++) {

			for(int j=nums.length-1; j>i; j--) {  // for(int j=i; j>0; j--) {
				
				if(nums[j-1] > nums[j]) {
					int temp = nums[j];
					nums[j] = nums[j-1];
					nums[j-1] = temp;
				}
			}
		}
		return nums;
	}

      Python 版本

def sortArray(self, nums):

    for i in range(0, len(nums)):
        for j in range(len(nums)-1, i-1, -1):
            if nums[j] < nums[j-1]:
                nums[j], nums[j-1] = nums[j-1], nums[j]
    
    return nums

     2、快速排序

      从数组中选取一个元素为基准元素,让每个元素依次和基准元素比较,比基准元素大的,交换到基准元素之后,比基准元素小的,交换到基准元素之前。

      再分别对基准元素前后的两组元素,重复上述操作,直到有序。

      Java 版本

// 递归快排
    public static void RecursiveSort(int[] nums, int low, int high) {
		
		if(low >= high)
			return;
		
		int mid = partition(nums, low, high);
		RecursiveSort(nums, low, mid-1);
		RecursiveSort(nums, mid+1, high);
	}
	
// 栈快排
	public static void StackSort(int[] nums, int low, int high) {
		
		Stack<Integer> stack = new Stack<Integer>();
		
		stack.push(high);
		stack.push(low);
		
		while(!stack.isEmpty()) {
			
			int left = stack.pop();
			int right = stack.pop();
			
			int mid = partition(nums, left, right);
			
			if(left < mid) {
				stack.push(mid-1);
				stack.push(left);
			}
			
			if(mid < right) {
				stack.push(right);
				stack.push(mid+1);
			}
		}
	}
	
	public static int partition(int[] nums, int low, int high) {
		
		int index = low;
		
		for(int i=low; i<high; i++) {
			
			if(nums[i] < nums[high]) {
				int temp = nums[i];
				nums[i] = nums[index];
				nums[index++] = temp;
			}
		}
		int temp = nums[high];
		nums[high] = nums[index];
		nums[index] = temp;
		return index;
	}

      Python 版本

def stack_sort(nums, low, high):
    stack = []

    stack.append(high)
    stack.append(low)

    while len(stack) > 0:

        left = stack.pop()
        right = stack.pop()
        mid = partition(nums, left, right)

        if left < mid:
            stack.append(mid - 1)
            stack.append(left)

        if mid < right:
            stack.append(right)
            stack.append(mid + 1)


def recursive_sort(nums, low, high):
    if low >= high:
        return

    mid = partition(nums, low, high)
    recursive_sort(nums, low, mid-1)
    recursive_sort(nums, mid+1, high)


def partition(nums, low, high):
    index = low
    for i in range(low, high):
        if nums[i] < nums[high]:
            nums[index], nums[i] = nums[i], nums[index]
            index += 1
    nums[index], nums[high] = nums[high], nums[index]
    return index

三、选择排序

     1、简单选择排序

      每次从无序区中选择最小的元素,和数组的第 i 个元素进行交换,直到全部有序。

      Java 版本

	public static int[] SelectSort(int[] nums) {
		
		for(int i=0; i<nums.length; i++) {
			int index = i;
			for(int j=i; j<nums.length; j++) {
				
				if(nums[index] > nums[j]) {
					index = j;
				}
			}
			int temp = nums[index];
			nums[index] = nums[i];
			nums[i] = temp;
		}
		return nums;
	}

       Python 版本

def sortArray(self, nums):

    for i in range(0, len(nums)):
        temp = nums[i]
        index = i
        for j in range(i+1, len(nums)):
            if temp > nums[j]:
                temp = nums[j]
                index = j
        nums[i], nums[index] = nums[index], nums[i]

    return nums

      2、堆排序

      将待排数组,看成完全二叉树,每次都通过比较父节点和左右子结点的大小,将最大/小的元素调整到根节点。重复,直到数组有序。

      Java 版本

    public static void heapSort(int[] nums) {
    	
        for (int i = (nums.length - 1)/2; i >= 0; i--)
            adjustHeap(nums, i, nums.length);

        for (int i = nums.length - 1; i > 0; i--) {

            int temp = nums[i];
            nums[i] = nums[0];
            nums[0] = temp;

            adjustHeap(nums, 0, i);
        }
    }

    private static void adjustHeap(int[] nums, int parent, int length) {  // 小根堆

        int temp = nums[parent];
        int maxlChild = 2 * parent + 1;

        while (maxlChild < length) {
            
            if (maxlChild+1 < length && nums[maxlChild] < nums[maxlChild+1])
            	maxlChild++;

            if (temp >= nums[maxlChild])
                break;

            nums[parent] = nums[maxlChild];

            parent = maxlChild;
            maxlChild = 2 * maxlChild + 1;
        }
        nums[parent] = temp;
    }

       Python 版本

def adjust_heap(self, nums, parent, length):
    temp = nums[parent]

    max_child = 2 * parent + 1

    while max_child < length:

        if max_child + 1 < length and nums[max_child] < nums[max_child+1]:
            max_child += 1
        
        if temp >= nums[max_child]:
            break

        nums[parent] = nums[max_child]
        parent = max_child
        max_child = max_child * 2 + 1
    
    nums[parent] = temp


def sortArray(self, nums):

    half = len(nums) // 2

    for i in range(half, -1, -1):
        adjust_heap(nums, i, len(nums))
    
    for i in range(len(nums)-1, 0, -1):
        nums[0], nums[i] = nums[i], nums[0]
        adjust_heap(nums, 0, i)

    return nums

四、归并排序

      通过递归思想,将数组分成两半,然后,递归合并两个有序子数组合。

      Java 版本

    public static int Merge(int[] nums, int left, int right) {
    	
    	if(left == right) return 0;
    		
		int mid = (left + right) / 2;
		
		int count = Merge(nums, left, mid) + Merge(nums, mid+1, right);
		count = megerSort(nums, left, mid, right, count);
		
		return count;
    }

	private static int megerSort(int[] nums, int left, int mid, int right, int count) {
		
		int len_l = mid - left + 1, len_r = right - mid;
		
		int[] l = new int[len_l];
		int[] r = new int[len_r];
		
		for(int i=0, k=left; i<len_l; i++)
			l[i] = nums[k++];
		
		for(int i=0, k=mid+1; i<len_r; i++)
			r[i] = nums[k++];
		
		int i, j, k;
		for(i=len_l-1,j=len_r-1,k=right; i>=0 && j>=0; k--) {
			
			if(l[i] > r[j]) {
				count += j + 1;  // 求逆序对,只多了这一行代码
				nums[k] = l[i--];
			}
			else
				nums[k] = r[j--];			
		}
		
		for(int x=i; x>=0; x--)
			nums[k--] = l[x];

		for(int x=j; x>=0; x--)
			nums[k--] = r[x];

		return count;
	}

      Python 版本

def merge_sort(nums, low, mid, high):
    left = []
    right = []

    for i in range(low, mid+1):
        left.append(nums[i])
    for i in range(mid+1, high+1):
        right.append(nums[i])

    index_l = 0
    index_r = 0
    index_nums = low

    while index_l < len(left) and index_r < len(right):
        if left[index_l] > right[index_r]:
            nums[index_nums] = right[index_r]
            index_r += 1
        else:
            nums[index_nums] = left[index_l]
            index_l += 1
        index_nums += 1

    if index_l < len(left):
        nums[index_nums] = left[index_l]
        index_l += 1
        index_nums += 1
    if index_r < len(right):
        nums[index_nums] = right[index_r]
        index_r += 1
        index_nums += 1
    print(nums)


def merge(nums, low, high):
    if low == high:
        return

    mid = int((low + high) / 2)
    merge(nums, low, mid)
    merge(nums, mid + 1, high)
    merge_sort(nums, low, mid, high)

五、编程题

问题描述:在一组字符串中,找到所有具有某个字符串前缀字符串,比如application、apple、eyes、cats等。如果要匹配的字符串是app,则符合匹配条件的有application、apple。

博客链接:百度面试题-字符串前缀匹配(二分法) - neyer - 博客园 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值