【算法】堆排、快速与归并排序

python实现


一:堆排序

堆排是利用堆的数据结构的性质进行排序,其时间复杂度为O(nlogn),其中空间复杂度为0(1),只利用一个单位做中间比较,它不是一个稳定的排序算法。

其主要算法步骤为:

  1. 创建一个堆H[0..n-1]
  2. 把堆首(最大值)和堆尾互换
  3. 把待排序数组的尺寸缩小1,并调用排序操作,把新的数组顶端数据调整到相应位置
  4. 重复步骤2,直到待排序数组为0

import os,MySort  
          
class HeapSort(MySort.MySort):  
     def __init__(self):    
        super(HeapSort, self).__init__("HeapSort", 8) #子类覆盖父类init方法,必须显式手动调用父类初始化方法。否则,父类不会主动初始化
        self.data = self.init()
       
     def sort(self):  
          i = (len(self.data) - 1)/2 #数组从1开始,第一位不考虑,这个地方应该减1。从1开始方便
          print self.data
          while i >= 1:
              self.heapSort(i)
              i = i - 1
              
     def heapSort(self, index):  
          array = self.data  
          length = len(array) - 1
          d = array[index]
          l = 2 * index # get its child
          while (l < length):
              if (l + 1) <= length:
                  ld = array[l]
                  rd = array[l + 1]
                  if rd < ld:
                      l = l + 1
              if l <= length and d > array[l]:
                  array[index] = array[l]
                  index = l
              l = 2 * l
              
          array[index] = d 
                 
     def pop(self):  
         result = self.data[0]  
         self.reHeap(array)  
         
     def reHeap(self, data):  
           pass
       
     def outName(self):  
         super(HeapSort, self).outName()  
           
     def outData(self):  
          super(HeapSort, self).outData()  
            
if __name__ == "__main__":  
     s = HeapSort()  
     s.outName()  
     s.sort()  
     s.outData() 

在这里也出一个关于堆的小题目,已知堆的高度为11,求堆的最大的节点个数和最小的节点个数?

堆我们一般认为是二叉堆,而其又是完全二叉树,所以第十一层最少一个元素,最多是满的,这就是最多与最小的个数。

二:快速排序

快速排序是对冒泡排序的改进算法,它通过一次排序把数据分分比某个数大的一边和比某个数小的一边,通过递归做次操作,直到排序完成。它是平均性能最好的排序,其最好的时间复杂度为O(nlgn),最坏情况则是O(n^2)。它也是一个不稳定的排序方式。

算法步骤:

1:从数列中挑出一个元素,称为“基准”(支点)

2:分别从数组的最左与最右开始比较,把左端大于基准的与右端小于基准的进行挑换,直到左边的指针大于右边的指针。然后把基准值插入数组。这样一步操作结束是基准值的左侧都比它小,右侧都比它大。

3:递归进行第二步操作。

# -*- coding = utf8 -*-
from MySort import MySort


class QuickSort(MySort):
    def __init__(self):
        super(QuickSort, self).__init__("QuickSort", 8)  
        self.data = self.init()    
    
    def quickSort(self):
        if self.data == None:
            return
        print(self.data)
        self.sort(0, len(self.data) - 1)
        print(self.data)
        
    def sort(self, begin, end):
        if begin == end: return
        index = end
        pk = self.data[index]
        low = begin
        high = end
        while True:
            while self.data[low] <= pk and low < high:
                low += 1
            
            while self.data[high] >= pk and low < high:
                high -= 1
                
            self.data[low], self.data[high] = self.data[high], self.data[low]
            print(self.data)
            if low >= high: break
        #insert pk, here you can use high or low,because they are equal
        self.data[high], self.data[index] = pk, self.data[high]
        print(self.data)
        if begin < low:
            self.sort(begin, low - 1)
        self.sort(low, end)
if __name__ == "__main__":
    instance = QuickSort()
    instance.quickSort()
    


java实现

对于排序算法来讲,它是一个搞频率使用的一个算法,在很多的数据结构和官方库里都有其具体的接口实现。因为它的应用广泛,在面试笔试中也是一个经常被提起的问题。这里就对几个常用的排序算法进行介绍。包括堆排,快排(快速排序)与归并排序。

父类,初始化测试数据,制定统一接口:


import java.util.Random;

public abstract class Sort {
	
	/**
	 * init the input data
	 */
	public int[] init(){
		int[] input = new int[8];//should get from conf
		for(int i = 0; i < 8; i ++){
			input[i] = new Random().nextInt(20);
		}
		for(int i : input){
			System.out.print(i + " ");
		}
		System.out.println();
		return input;
	};

	/**
	 * main logic
	 */
	public abstract void sort();

	public abstract void printResult();
}

快排,利用了分治思想,是冒泡的升级。大多数情况下可以保持n*logn的复杂度,极端情况下会退化成冒泡,n*n的复杂度

public class QuickSort extends Sort {
	private int[] input;

	@Override
	public int[] init() {
		input = super.init();
		return input;
	}

	@Override
	public void sort() {
		int end = input.length;
		sort(0, end - 1);
	}

	private void sort(int begin, int end) {
		if (begin == end)
			return;
		int index = end;
		int pk = input[end];
		int low = begin;
		int high = end;
		while (true) {
			while (input[low] <= pk && low < high)
				low++;
			while (input[high] >= pk && low < high)
				high--;
			int tmp = input[low];
			input[low] = input[high];
			input[high] = tmp;
			if (low == high)
				break;
		}
		int tmp = input[low];
		input[low] = pk;
		input[index] = tmp;
		if (begin < low) {
			sort(begin, low - 1);
		}
		sort(low, end);
	}

	@Override
	public void printResult() {
		for (int i : input) {
			System.out.print(i + " ");
		}
	}

	public static void main(String[] args) {
		QuickSort qs = new QuickSort();
		qs.init();
		qs.sort();
		qs.printResult();
	}
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值