排序算法

demo.cpp:

#include <iostream>
#include "my_sort.h"

int main(void)
{
	using namespace std;

	const int SIZE = 30;
	int arr[SIZE] = {1,1,9,9,6,6,8,8,4,4,0,0,7,7,5,5,2,2,3,3,1,9,6,8,4,0,7,5,2,3};

	//InsertSort(arr, SIZE);
	//BinarySort(arr, SIZE);
	//BubbleSort(arr, SIZE);
	//SelectSort(arr, SIZE);
	//HeapSort(arr, SIZE);
	//QuickSort(arr, SIZE);
	//NonrecursiveQuickSort(arr, SIZE);
	//MergeSort(arr, SIZE);
	//NonrecursiveQuickSort(arr, SIZE);
	//ShellSort(arr, SIZE);
	RadixSort(arr, SIZE);
	for (int i = 0; i < SIZE; ++i)
	{
		cout << arr[i] << endl;
	}
	return 0;
}

 

 

my_sort.h:

//sort integer numbers in ascending order
//for RadixSort, use LSD strategy and handle non-negative integer
#ifndef __MY_SORT
#define __MY_SORT
#include <cmath>

void InsertSort(int *arr, const int size);
void BinarySort(int *arr, const int size);
void BubbleSort(int *arr, const int size);
void SelectSort(int *arr, const int size);
void HeapSort(int *arr, const int size);
void QuickSort(int *arr, const int size);
void NonrecursiveQuickSort(int *arr, const int size);
void MergeSort(int *arr, const int size);
void NonrecursiveMergeSort(int *arr, const int size);
void ShellSort(int *arr, const int size);
void RadixSort(int *arr, const int size);

#endif

 

 

my_sort.cpp:

 

#include "my_sort.h"

void InsertSort(int *arr, const int size)
{
	for (int i = 1; i < size; ++i)
	{
		int temp = arr[i];
		int j;
		for (j = i-1; j >= 0 ; --j)
		{
			if (temp < arr[j])
			{
				arr[j+1] = arr[j];
			}
			else
			{
				break;
			}
		}
		arr[j+1] = temp;
	}
	return;
}

int BinarySearch(int *arr, int target, int size)
{
	int left = 0;
	int right = size - 1;
	int middle;
	while (left <= right)
	{
		middle = (left + right)/2;
		if (target < arr[middle])
		{
			right = middle - 1;
		}
		else
		{
			left = middle + 1;
		}
	}
	return left;
}
void BinarySort(int *arr, const int size)
{
	for (int temp, idx, i = 1; i < size; ++i)
	{
		temp = arr[i];
		idx = BinarySearch(arr, temp, i);
		for (int j = i-1; j >= idx; --j)
		{
			arr[j+1] = arr[j];
		}
		arr[idx] = temp;
	}
	return;
}

void BubbleSort(int *arr, const int size)
{
	bool isChanged = true;
	for (int i = size - 1; isChanged && i > 0; --i)
	{
		isChanged = false;
		for (int j = 1; j <= i; ++j)
		{
			if (arr[j] < arr[j-1])
			{
				isChanged = true;
				arr[j] ^= arr[j-1];
				arr[j-1] ^= arr[j];
				arr[j] ^= arr[j-1];
			}
		}	
	}
	return;
}

void SelectSort(int *arr, const int size)
{
	for (int i = 0; i < size; ++i)
	{
		int k = i;
		for (int j = i + 1; j < size; ++j)
		{
			if (arr[j] < arr[k])
			{
				k = j;
			}
		}
		if (k != i)
		{
			arr[i] ^= arr[k];
			arr[k] ^= arr[i];
			arr[i] ^= arr[k];
		}
	}
	return;
}

void CreateBigRootHeap(int *arr, int rt_idx, int size)
{//create big-root heap
	int temp;
	while (2*rt_idx + 1 < size)
	{
		temp = 2*rt_idx + 1;
		if (temp + 1 < size)
		{
			if (arr[temp] < arr[temp + 1])
			{
				++temp;
			}
		}
		if (arr[rt_idx] < arr[temp])
		{//the heap may be disturbed and need reordering
			arr[rt_idx] ^= arr[temp];
			arr[temp] ^= arr[rt_idx];
			arr[rt_idx] ^= arr[temp];

			rt_idx = temp;
		}
		else
		{
			break;
		}
	}
	return;
}
void HeapSort(int *arr, const int size)
{
	//Firtly, ceate big-root heap first
	for (int i = size/2 - 1; i >= 0; --i)
	{
		CreateBigRootHeap(arr, i, size);
	}
	for (int i = size - 1; i > 0; --i)
	{
		//make an element be in the right order
		arr[0] ^= arr[i];
		arr[i] ^= arr[0];
		arr[0] ^= arr[i];

		//reorder to make the rest be big-root heap
		CreateBigRootHeap(arr, 0, i);
	}
	return;
}

int Partition(int *arr, int left, int right)
{
	int temp = arr[left];
	while (left < right)
	{
		while (left < right)
		{
			if(temp <= arr[right])
			{
				--right;
			}
			else
			{
				arr[left++] = arr[right];
				break;
			}
		}
		while (left < right)
		{
			if (arr[left] <= temp)
			{
				++left;
			}
			else
			{
				arr[right--] = arr[left];
				break;
			}
		}
	}		
	arr[left] = temp;
	return left;
}
void MyQuickSort(int *arr, int beg, int end)
{
	if (beg < end)
	{
		int p_idx = Partition(arr, beg, end);
		MyQuickSort(arr, beg, p_idx - 1);
		MyQuickSort(arr, p_idx + 1, end);
	}
	return;
}
void QuickSort(int *arr, const int size)
{
	MyQuickSort(arr, 0, size - 1);
	return;
}
void NonrecursiveQuickSort(int *arr, const int size)
{
	int beg = 0, end = size - 1;
	if (beg < end)
	{
		const int SIZE = 30;//change along with the size of the sequence.
		struct
		{
			int beg;
			int end;
		}st[SIZE];
		int ptr = 0, idx;
		st[ptr].beg = beg;st[ptr].end = end;++ptr;
		while (ptr)
		{
			--ptr;beg = st[ptr].beg;end = st[ptr].end;
			idx = Partition(arr, beg, end);
			if (beg < idx - 1)
			{
				st[ptr].beg = beg;st[ptr].end = idx - 1;++ptr;
			}
			if (idx + 1 < end)
			{
				st[ptr].beg = idx + 1;st[ptr].end = end;++ptr;
			}
		}
	}
	return;
}

void MergeArray(int *arr, int beg1, int end1, int beg2, int end2, int *temp)
{//in fact, (end1 + 1) must be equal to beg2 in this implementation.
	int m1 = beg1, n1 = end1, m2 = beg2, n2 = end2;
	int idx = 0;
	while (m1 <= n1 && m2 <= n2)
	{
		temp[idx++] = (arr[m2] < arr[m1])?arr[m2++]:arr[m1++];
		
	}
	while (m1 <= n1)
	{
		arr[--m2] = arr[n1--];	//this trick can reduce the unnecessary element move
	}
	while (idx > 0)
	{
		arr[--m2] = temp[--idx];
	}
}
void MyMergeSort(int *arr, int beg, int end, int *temp)
{
	if (beg < end)
	{
		int mid = (beg + end)/2;
		MyMergeSort(arr, beg, mid, temp);
		MyMergeSort(arr, mid + 1, end, temp);
		MergeArray(arr, beg, mid, mid + 1, end, temp);
	}
	return;
}
void MergeSort(int *arr, const int size)
{
	if(0 < size)
	{
		int *temp = new int[size];
		MyMergeSort(arr, 0, size - 1, temp);
		delete[] temp;
	}
}
void NonrecursiveMergeSort(int *arr, const int size)
{
	if (0 < size)
	{
		int *temp = new int[size];
		int m1, n1, m2, n2;
		for (int step = 1; step < size; step *=2)
		{
			for(m1 = 0; m1 < size - step; m1 = n2)
			{
				n1 = m2 = m1 + step;
				n2 = m2 + step;
				if (n2 > size)
				{
					n2 = size;
				}
				MergeArray(arr, m1, n1 - 1, m2, n2 - 1, temp);
			}
		}
		delete[] temp;
	}
	return;
}

void ShellSort(int *arr, const int size)
{
	for (int i, j, temp, step = size/2; step > 0; step /= 2)
	{
		for (i = step; i < size; ++i)
		{
			temp = arr[i];
			j = i - step;
			while (j >= 0 && temp < arr[j])
			{
				arr[j+step] = arr[j];
				j -= step;
			}
			arr[j+step] = temp;
		}
	}
	return;
}

int GetMaxElement(int *arr, const int size)
{
	int temp = 0;
	if (0 < size)
	{
		temp = arr[0];
		for (int i = 1; i < size; ++i)
		{
			if (temp < arr[i])
			{
				temp = arr[i];
			}
		}
	}
	return temp;
}
int GetLoopTimes(int elem)
{
	const int radix = 10;
	int num = 0;
	do{
		++num;
	}while(elem /= 10);
	
	return num;
}
void OnePassRadixSort(int *arr, const int size, int digit_pos)
{
	const int radix = 10;
	int *temp = new int[size*radix];
	int *counts = new int[radix];

	int t = 1;
	while (--digit_pos)
	{
		t *= radix;
	}

	for (int i = 0; i < radix; ++i)
	{
		*(counts + i) = 0;
	}
	for (int i = 0; i < size; ++i)
	{
		int d = arr[i]/t%radix;
		temp[d*size+(*(counts+d))++] = arr[i];
	}
	int i = 0;
	for (int d = 0; d < radix; ++d)
	{
		for (int k = 0; k < *(counts+d); ++k)
		{
			arr[i++] = temp[d*size+k];
		}
	}
	return;
}
void RadixSort(int *arr, const int size)
{
	if (0 < size)
	{
		int max_elem = GetMaxElement(arr, size);
		int loop_times = GetLoopTimes(max_elem);

		for (int i = 1; i <= loop_times; ++i)
		{
			OnePassRadixSort(arr, size, i);
		}
	}
	return;
}

Java Implementation:

package com.huawei.test;

import java.util.Arrays;
import java.util.Stack;

public class SortTools {

    public static void main(String[] args) {
        System.out.println("mySortTool");
        int[] arr = new int[] { 4, 2, 3, 1, 5, -1, 2, 3, -1, -2, 0 };
        int[] arr1 = new int[] { 4, 2, 3, 1, 5, 11, 2, 3, 12, 10, 0 };
        // bubbleSort(arr);
        // insertSort(arr);
        // binaryInsertSort(arr);
        // selectSort(arr);
        // heapSort(arr);
        // quickSort(arr);
        // nonRecursiveQuickSort(arr);
        // mergeSort(arr);
        // nonRecursiceMergeSort(arr);
        // shellSort(arr);
        radixSortLSD(arr1);
        System.out.print(Arrays.toString(arr1));
    }

    private static void swap(int[] arr, int a, int b) {
        arr[a] ^= arr[b];
        arr[b] ^= arr[a];
        arr[a] ^= arr[b];
    }

    /**
     * bubble sort time Complexity: O(n^2) space Complexity: O(1) stability: stable
     *
     * @param arr data need to be sorted
     */
    public static void bubbleSort(int[] arr) {
        if ((arr == null) || (arr.length < 2)) {
            return;
        }

        boolean isNeedTry = true;
        for (int j, i = 0; (i < (arr.length - 1) && isNeedTry); i++) { // each traversal settle an element
            isNeedTry = false;
            for (j = i + 1; j < arr.length; j++) { // find the final element for position (arr.length - 1 - i)
                if (arr[j - 1] > arr[j]) {
                    // swap
                    swap(arr, j - 1, j);
                    isNeedTry = true;
                }
            }
        }
    }

    /**
     * insert sort. time Complexity: O(n^2), space Complexity: O(1), stability:
     * stable
     *
     * @param arr data need to be sorted
     */
    public static void insertSort(int[] arr) {
        if ((arr == null) || (arr.length < 2)) {
            return;
        }

        for (int temp, j, i = 1; i < arr.length; i++) { // each traversal settle an element
            temp = arr[i];
            for (j = i - 1; j != 0; j--) { // find the final position for element i
                if (temp < arr[j]) {
                    arr[j + 1] = arr[j];
                } else {
                    break;
                }
            }
            arr[j + 1] = temp;
        }
    }

    /**
     * find the right position for target to put when inserted into an increasing
     * sequence
     *
     * @param arr    increasing sequence
     * @param begin  start position of the increasing sequence
     * @param end    end position of the increasing sequence
     * @param target element need to be inserted
     * @return
     */
    private static int binarySearch(int[] arr, int begin, int end, int target) {
        int left = begin;
        int right = end;
        int mid;

        while (left <= right) {
            mid = (begin + end) / 2;
            if (target >= arr[mid]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return left;
    }

    /**
     * binary search insert sort. time Complexity: O(n^2), space Complexity: O(1),
     * stability: stable
     *
     * @param arr data need to be sorted
     */
    public static void binaryInsertSort(int[] arr) {
        if ((arr == null) || (arr.length < 2)) {
            return;
        }

        for (int temp, idx, j, i = 1; i < arr.length; i++) { // each traversal settle an element
            temp = arr[i];
            idx = binarySearch(arr, 0, i - 1, arr[i]); // find the final position for element i, decrease compare
                                                       // operation
            for (j = i; j > idx; j--) {
                arr[j] = arr[j - 1];
            }
            arr[idx] = temp;
        }
    }

    /**
     * select sort. time Complexity: O(n^2), space Complexity: O(1), stability:
     * unstable
     *
     * @param arr data need to be sorted
     */
    public static void selectSort(int[] arr) {
        if ((arr == null) || (arr.length < 2)) {
            return;
        }

        for (int k, j, i = 0; i < (arr.length - 1); i++) { // each traversal settle an element
            k = i;
            for (j = (i + 1); j < arr.length; j++) { // find the final position for element i
                if (arr[k] > arr[j]) {
                    k = j;
                }
            }
            if (k != i) { // swap
                swap(arr, k, i);
            }
        }
    }

    /**
     * make a binary tree be big-root heap on condition that the child binary trees
     * are all big-root heap
     *
     * @param arr    the whole sequence need to be handled
     * @param parent the root of the sub binary tree
     * @param size   the size of the whole binary tree
     */
    private static void adjustToBigRootHeap(int[] arr, int parentIdx, int size) {
        int bigIdx;
        while ((bigIdx = (parentIdx * 2) + 1) < size) {
            if (((bigIdx + 1) < size) && (arr[bigIdx] < arr[bigIdx + 1])) {
                bigIdx = bigIdx + 1;
            }
            if (arr[parentIdx] < arr[bigIdx]) {
                swap(arr, parentIdx, bigIdx);
                parentIdx = bigIdx;
            } else {
                break;
            }
        }
    }

    /**
     * make the sequence be big-root heap
     *
     * @param arr sequence need to be handled
     */
    private static void createBigRootHeap(int[] arr) {
        for (int i = ((arr.length / 2) - 1); i >= 0; i--) {
            adjustToBigRootHeap(arr, i, arr.length);
        }
    }

    /**
     * heap sort. time Complexity: O(n*log(n)), space Complexity: O(1), stability:
     * unstable
     *
     * @param arr data need to be sorted
     */
    public static void heapSort(int[] arr) {
        if ((arr == null) || (arr.length < 2)) {
            return;
        }

        // firstly, make the array be a big-root heap
        createBigRootHeap(arr);

        // secondly, make the array be increasing order
        for (int i = (arr.length - 1); i > 0; i--) {
            swap(arr, 0, i); // set the biggest element to the final position
            adjustToBigRootHeap(arr, 0, i); // make the rest element keep being big-root heap
        }
    }

    /**
     * split the sequence into two part based on element begin, elements in the left
     * part are all smaller than element begin, elements in the right part are all
     * bigger than element begin.
     *
     * @param arr   sequence need to be handled
     * @param begin the beginning position of the sequence
     * @param end   the ending position of the sequence
     * @return the partition position
     */
    private static int partition(int[] arr, int begin, int end) {
        int temp = arr[begin];
        while (begin < end) {
            while (begin < end) {
                if (temp <= arr[end]) {
                    end--;
                } else {
                    arr[begin++] = arr[end];
                    break;
                }
            }
            while (begin < end) {
                if (arr[begin] <= temp) {
                    begin++;
                } else {
                    arr[end--] = arr[begin];
                    break;
                }
            }
        }
        arr[begin] = temp;
        return begin;
    }

    /**
     * sort the sequence in a recursive way
     *
     * @param arr   sequence need to be handled
     * @param begin the beginning position of the sequence
     * @param end   the ending position of the sequence
     */
    private static void myQuickSort(int[] arr, int begin, int end) {
        if (begin >= end) {
            return;
        }
        int partitionIdx = partition(arr, begin, end);
        myQuickSort(arr, begin, partitionIdx - 1);
        myQuickSort(arr, partitionIdx + 1, end);
    }

    /**
     * quick sort. time Complexity: O(n*log(n)), space Complexity: O(log(n)),
     * stability: unstable. (at the worst situation, time Complexity: O(n^2),
     * Complexity: O(n))
     *
     * @param arr data need to be sorted
     */
    public static void quickSort(int[] arr) {
        if ((arr == null) || (arr.length < 2)) {
            return;
        }

        myQuickSort(arr, 0, arr.length - 1);
    }

    /**
     * non recursive quick sort. time Complexity: O(n*log(n)), space Complexity:
     * O(log(n)), stability: unstable. (at the worst situation, time Complexity:
     * O(n^2), Complexity: O(n))
     *
     * @param arr data need to be sorted
     */
    public static void nonRecursiveQuickSort(int[] arr) {
        if ((arr == null) || (arr.length < 2)) {
            return;
        }

        class Pair<A, B> {
            A first;
            B second;

            Pair(A a, B b) {
                first = a;
                second = b;
            }
        }

        Stack<Pair<Integer, Integer>> sortStates = new Stack<Pair<Integer, Integer>>();
        sortStates.push(new Pair<Integer, Integer>(0, arr.length - 1));
        while (!sortStates.isEmpty()) {
            Pair<Integer, Integer> sortPair = sortStates.pop();
            if (sortPair.first < sortPair.second) {
                int pivotalIdx = partition(arr, sortPair.first, sortPair.second);
                sortStates.push(new Pair<Integer, Integer>(sortPair.first, pivotalIdx - 1));
                sortStates.push(new Pair<Integer, Integer>(pivotalIdx + 1, sortPair.second));
            }
        }
    }

    /**
     * merge two sequence in increasing order into one sequence with increasing
     * order
     *
     * @param assist the temporary space to perform the merge action
     * @param arr    sequence need to be handled
     * @param beg1   the beginning position of the first sequence
     * @param end1   the ending position of the first sequence
     * @param beg2   the beginning position of the second sequence
     * @param end2   the ending position of the second sequence
     */
    private static void merge(int[] assist, int[] arr, int beg1, int end1, int beg2, int end2) {
        // in fact, (end1 + 1) must be equal to beg2 in this implementation.
        int i = 0;
        while ((beg1 <= end1) && (beg2 <= end2)) {
            assist[i++] = (arr[beg1] < arr[beg2]) ? arr[beg1++] : arr[beg2++];
        }
        while (beg1 <= end1) {
            // this trick can reduce the unnecessary element move
            arr[--beg2] = arr[end1--];
        }
        while (i > 0) {
            arr[--beg2] = assist[--i];
        }
    }

    /**
     * sort the sequence in a recursive way
     *
     * @param assist the temporary space to perform the merge action
     * @param arr    sequence need to be handled
     * @param beg    the beginning position of the sequence
     * @param end    the ending position of the sequence
     */
    private static void myMergeSort(int[] assist, int[] arr, int beg, int end) {
        if (beg < end) {
            int mid = ((beg + end) / 2);
            myMergeSort(assist, arr, beg, mid);
            myMergeSort(assist, arr, (mid + 1), end);
            merge(assist, arr, beg, mid, (mid + 1), end);
        }
    }

    /**
     * recursive merge sort. time Complexity: O(n*log(n)), space Complexity: O(n),
     * stability: stable.
     *
     * @param arr data need to be sorted
     */
    public static void mergeSort(int[] arr) {
        if ((arr == null) || (arr.length < 2)) {
            return;
        }
        int[] assist = new int[arr.length];
        myMergeSort(assist, arr, 0, arr.length - 1);
    }

    /**
     * non recursive merge sort. time Complexity: O(n*log(n)), space Complexity:
     * O(n), stability: stable.
     *
     * @param arr data need to be sorted
     */
    public static void nonRecursiceMergeSort(int[] arr) {
        if ((arr == null) || (arr.length < 2)) {
            return;
        }
        int[] assist = new int[arr.length];

        for (int beg, mid, end, step = 1; step < arr.length; step *= 2) {
            for (beg = 0; (mid = (beg + step)) < arr.length; beg += 2 * step) {
                end = ((mid + step) < arr.length) ? (mid + step - 1) : (arr.length - 1);
                merge(assist, arr, beg, mid - 1, mid, end);
            }
        }
    }

    /**
     * shell sort(diminishing increment sort). time Complexity: O(n*log(2n)), space
     * Complexity: O(1), stability: unstable. Shell Increment: N/(2^1), N/(2^2),
     * ..., 1}, time Complexity O(n^2), O(n*log(2n)). Hibbard Increment: time
     * Complexity O(n^1.5)
     *
     * @param arr data need to be sorted
     */
    public static void shellSort(int[] arr) {
        if ((arr == null) || (arr.length < 2)) {
            return;
        }

        for (int i, j, temp, delta = (arr.length / 2); delta > 0; delta /= 2) {
            for (i = delta; (j = i) < arr.length; i++) {
                temp = arr[i];
                while (((j -= delta) >= 0) && arr[j] > temp) {
                    arr[j + delta] = arr[j];
                }
                arr[j + delta] = temp;
            }
        }
    }

    /**
     * radix sort(least significant digit). time Complexity: O(d*n), space
     * Complexity: O(n), stability: stable.
     */
    public static void radixSortLSD(int[] arr) {
        if ((arr == null) || (arr.length < 2)) {
            return;
        }

        // find max value
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (max < arr[i]) {
                max = arr[i];
            }
        }

        final int RADIX = 10;
        int[] assist = new int[arr.length];

        for (int exp = 1; (max / exp) > 0; exp *= RADIX) {// n times of dispatch and collect
            int[] bucket = new int[RADIX];

            for (int i = 0; i < arr.length; i++) {// count for each radix
                bucket[((arr[i] / exp) % RADIX)]++;
            }

            for (int i = 1; i < RADIX; i++) {// calculate increment number
                bucket[i] += bucket[i - 1];
            }

            for (int i = arr.length - 1; i >= 0; i--) {// dispatch and collect on the temporary space
                assist[--bucket[((arr[i] / exp) % RADIX)]] = arr[i];
            }

            for (int i = 0; i < arr.length; i++) {// store into the final space
                arr[i] = assist[i];
            }
        }
    }

}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值