zoukankan      html  css  js  c++  java
  • 数据结构——排序(C++代码的具体实现无分析)

    排序

    冒泡排序

    template <typename T>
    void BubbleSort(vector<T>& list)
    {
        const int n = list.size();  
        for (int i = 0; i < n - 1; i++)
        {
            for (int j = n - 1; j > i; j--)
                if (list[j] < list[j - 1])
                    swap(list[j], list[j - 1]);
        }
    }
    
    

    插入排序

    1. 直接插入排序

    直接插入排序对本来已经大致有序的序列效率较高

    template<typename T>
    void InsertSort(vector<T>& list,int sizeOfSorted=1) 
    {
        const int n = list.size();
        for (int i = sizeOfSorted; i <= n-1; i++)
        {
            T temp = list[i];
            int j = i - 1;
            for ( j = i-1; j >= 0 && temp < list[j]; j--)
            {
                list[j+1] =list[j];
            }
            list[j+1] = temp;
        }
    }
    

    1.折半插入排序

    注意:

    • while 循环的条件包括 =, 和high = mid-1以及low = mid+1可以保证当循环结束时, 要插入的位置刚好是当前 low 的前一位.
    • 随着不断插入, low 和 high 每次循环时都要重新赋值.
    template<typename T>
    void BinaryInsertSort(vector<T>& list,const int sizeOfSorted=1)
    {
        const int n = list.size();
        int low = 0;
        int high = sizeOfSorted - 1;
        int mid = 0;
        for (int i = sizeOfSorted; i < n; i++)
        {
            T temp = list[i];
            high = i - 1; low = 0;
            while (low<=high)
            {
                mid = (low + high) / 2;
                if (list[mid] > list[i])
                    high = mid-1;
                else
                    low = mid+1;
    
            }
            for (int j = i; j > low; j--)
                list[j] = list[j - 1];
            list[low] = temp;
        }
    }
    

    3. 希尔排序法

    template<typename T>
    void ShellInsertSort(vector<T>& list)
    {
        int gap = 0;
        const int n = list.size();
        for (gap = list.size() / 3; gap > 0; gap = gap / 3 + 1)
        {
            //各个子列轮流做直接插入, 将每个子列第零个元素设为基准
            for (int i = gap; i < n; i++)
            {
                T temp = list[i];
                int j = 0;
                for ( j = i - gap;  j >= 0 && temp < list[j] ; j -= gap)
                {
                    list[j + gap] = list[j];
                }
                list[j + gap] = temp;
            }
            if (gap == 1) break;
        }
    }
    

    快速排序法

    通过一趟排序将序列分为左右两个子序列, 其中左序列所有的数据都小于右序列, 然后对这两个子序列进行快速排序,整个排序过程递归进行.
    最好情况:元素均匀分布
    最坏情况:基准为子序列最大或最小值

    快速排序

    //双指针
    template <typename T>
    int FindPos(vector<T>& list,const int left,const int right)
    {
        T base = list[left];
        int smallerPos = left;
        int greaterPos = right;
        while ( smallerPos< greaterPos) {
            while (list[greaterPos] >= base && smallerPos < greaterPos)
            {
                greaterPos--;
            }
            list[smallerPos] = list[greaterPos];
            while (list[smallerPos] <= base && smallerPos < greaterPos)
            {
                smallerPos++;
            }
            list[greaterPos] = list[smallerPos]; 
        }
        list[smallerPos] = base;
        return smallerPos;
    }
    //普通
    template <typename T>
    int FindPos(vector<T>& list, int left, int right) 
    {
        T base = list[left];
        int smallerPos =left;
        for(int i=left+1;i<=right;i++)
        {
            if(list[i]<base)
            {
                smallerPos++;
                if(i!=smallerPos)
                    swap(list[smallerPos],list[i]);
            }
        }
        swap(list[left],list[smallerPos]);
        return smallerPos;
    }
    
    template <typename T>
    void QuickSort(vector<T>& list,int left,int right) 
    {
        if (left < right) {
            int pos = FindPos(list, left, right);
            QuickSort(list, left,	pos - 1);
            QuickSort(list, pos + 1, right);
        }
    }
    

    2.三路划分快速排序

    template <typename T>
    void QuickSort(vector<T>& list, int left, int right)
    {
        if (left >= right) return;
        T base = list[left];
        int lessPos = left;
        int greaterPos = right + 1;
        for (int i = left + 1; i < greaterPos; i++)
        {
            if (list[i] < base)
                swap(list[++lessPos], list[i]);
            else if (list[i] > base)
            {
                swap(list[i], list[--greaterPos]);
                i--;
            }
        }
        swap(list[left], list[lessPos]);
        QuickSort(list, left, lessPos - 1);
        QuickSort(list, greaterPos, right);
    }
    

    选择排序

    1. 直接选择

    template<typename T>
    void selectSort(vector<T>& list)
    {
        for (int i = 0; i < list.size(); i++)
        {
            int indexOfmin = i;
            int j;
            for (j = i + 1; j < list.size(); j++)
            {
                if (list[j] < list[indexOfmin]) indexOfmin = j;
            }
            swap(list[i], list[indexOfmin]);
        }
    }
    

    2.堆排序

    #pragma once
    #include <iostream>
    #include <vector>
    //第二个模板参数是比较器
    using std::vector;
    template <typename _Ty, typename _Com>
    class priorityQueue
    {
    public:
    	priorityQueue() {}
    	priorityQueue(vector<_Ty>& arrays) :heap(arrays),start(0),end(arrays.size()-1)
    	{
    		siftDown();
    	}
    	priorityQueue( vector<_Ty>& arrays,int start,int end) :heap(arrays), start(start), end(end)
    	{
    		siftDown();
    	}
    	~priorityQueue() {}
    	void pop();
    	void push(const _Ty& item);
    	_Ty& top() { return heap[0]; };
    protected:
    private:
    	void siftDown(int startSift=-1);
    	void siftUp();
    	vector<_Ty>& heap;
    	int start;//起始位置下标
    	int end;//结束位置下标
    };
    
    
    template <typename _Ty, typename _Com>
    void priorityQueue<_Ty, _Com>::push(const _Ty& item)
    {
    	heap.push_back(item);
    	siftUp();
    }
    
    template <typename _Ty, typename _Com>
    void priorityQueue<_Ty, _Com>::siftDown(int startSift)
    {
    	//i,j 为偏移索引, start, end, startSift, endSift 为实际索引
    	if (start>=end)
    	{
    		return;
    	}
    	_Com comparator;
    	if (startSift == -1)
    	{
    		startSift = (end-start-1)/2+start;
    	}
    	for (size_t endSift = end; startSift-start >= 0; startSift--)
    	{
    		size_t i = startSift-start;
    		size_t j = 2 * i + 1;//i 的左孩子
    		_Ty temp = heap[i+start];
    		while (j+start <= endSift) {
    			if (j+start < endSift && comparator(heap[j+start], heap[j + 1+ start]))
    				j++;//j 指向更小的那个孩子
    			if (comparator(temp, heap[j+ start]))
    			{
    				heap[i+ start] = heap[j+ start];
    				i = j;
    				j = 2 * i + 1;
    			}
    			else
    				break;
    		}
    		heap[i+ start] = temp;
    	}
    }
    
    template <typename _Ty, typename _Com>
    void priorityQueue<_Ty, _Com>::siftUp()
    {
    	_Com com();
    	size_t i = end;
    	_Ty temp = heap[i];
    	for (size_t j = (i - 1) / 2; i > 0;)
    	{
    		if (j >= 0 && com(heap[j], temp))
    		{
    			heap[i] = heap[j];
    			i = j;
    			j = (i - 1) / 2;
    		}
    		else
    			break;
    	}
    	heap[i] = temp;
    
    }
    
    
    template <typename _Ty, typename _Com>
    void priorityQueue<_Ty, _Com>::pop()
    {
    	_Ty temp = heap[start];
    	heap[start] = heap[end];
    	heap[end] = temp;
    	end--;
    	siftDown(start);
    }
    
    //堆排序, 建立最大堆, 依次将根节点与最后一个元素交换, 然后再次调整为最大堆
    template<class _Ty>
    void HeapSort(vector<_Ty>& num, int start, int end)
    {
        auto comparator = [](_Ty a, _Ty b){return b >a; };
        priorityQueue<_Ty, decltype(comparator)> maxHeap(num,start,end);
        for (int i = start; i <= end; i++)
            maxHeap.pop();
    }
    int main()
    {
    	vector<int> num({ 9,8,7,6,5,4,3,2,1 });
    	HeapSort(num, 6, 8);
    	for (size_t i = 0; i < num.size(); i++)
    	{
    		std::cout << num[i] << " ";
    	}
    }
    
    

    基数排序

    void radixSort(vector<int>& array)
    {
    	vector<vector<int>> bucket(10);
    	int max=array[0];
    	for (int i = 1; i < array.size(); i++)
    	{
    		if (max < array[i]) max = array[i];
    	}
    	for (int round = 1; round <=max; round *= 10)
    	{
    		//进桶
    
    		for (int i = 0; i < array.size(); i++)
    		{
    			bucket[((array[i]) / round) % 10].push_back(array[i]);
    		}
    		int count = 0;
    		int i = 0;
    		while (count != array.size())
    		{
    			while (!bucket[i].empty())
    			{
    				array[count++] = bucket[i].front();
    				bucket[i].erase(bucket[i].begin());
    			}
    			i++;
    		}
    	}
    }
    
  • 相关阅读:
    LeetCode 42. Trapping Rain Water
    LeetCode 209. Minimum Size Subarray Sum
    LeetCode 50. Pow(x, n)
    LeetCode 80. Remove Duplicates from Sorted Array II
    Window10 激活
    Premiere 关键帧缩放
    AE 「酷酷的藤」特效字幕制作方法
    51Talk第一天 培训系列1
    Premiere 视频转场
    Premiere 暴徒生活Thug Life
  • 原文地址:https://www.cnblogs.com/Jyaoushingan/p/14275301.html
Copyright © 2011-2022 走看看