1 十大排序算法


Java实现:
https://blog.csdn.net/meibenxiang/article/details/92796909?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162790074316780255231156%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162790074316780255231156&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2 allfirst_rank_v2~rank_v29-2-92796909.pc_search_result_cache&utm_term=排序算法&spm=1018.2226.3001.4187

C++实现:
https://blog.csdn.net/kuaizi_sophia/article/details/87954222?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162795458816780274117377%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162795458816780274117377&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-1-87954222.pc_search_result_cache&utm_term=排序算法C%2B%2B&spm=1018.2226.3001.4187

一 冒泡排序

  • 比较相邻的元素。如果第一个比第二个大,就交换它们两个
  • 从小到大

1 C++实现

#include<iostream>
using namespace std;
#include<string>
#include<vector>
// 冒泡排序
void bubbleSort(vector<int>& array) {
    for (size_t i = 0; i < array.size(); i++) {
    // 当前轮是否发生过交换事件标志位,若未发生交换,则表明列表已有序
        bool isExchanged = false;
        for (size_t j = 0; j < array.size() - i - 1; j++) {
            if (array[j] > array[j + 1]) {
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
                isExchanged = true;
            }
        }
        if (!isExchanged){
            break;
        }
    }
}

2 Java实现

public static int[] bubbleSort(int[] array){
		if(array.length > 0){
			for(int i = 0;i<array.length;i++){
				for(int j = 0;j<array.length - 1 - i;j++){
					if(array[j] > array[j+1]){
						int temp = array[j];
						array[j] = array[j+1];
						array[j+1] = temp;
					}
				}
			}
		}
		return array;

二 选择排序

  • 搜索整个列表,找出最小项/最大项,若此项不为第1项,则与第1项交换位置
  • 从小到大/从大到小

1 C++实现

// 选择排序
void selectSort(vector<int>& array){
    for (size_t i = 0; i < array.size(); i++){
        size_t minIndex = i;
        for (size_t j = i + 1; j < array.size(); j++){
            if (array[minIndex] > array[j]){
                minIndex = j;
            }
        }
        if (minIndex != i){
            swap(array[i], array[minIndex]);
        }
    }
}

2 Java实现

public static int[] selectionSort(int[] array){
		if(array.length > 0){
			for(int i = 0;i<array.length;i++){
				int minIndex = i;
				for(int j = i;j<array.length;j++){
				//遍历未剩余未排序元素中继续寻找最小元素
					if(array[j] < array[minIndex]){
						minIndex = j;
					}
				}
				if(minIndex != i){
					int temp = array[minIndex];
					array[minIndex] = array[i];
					array[i] = temp;
				}
			}	
		}
		return array;
	}

三 插入排序

  • 从小到大
  • 通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入

1 c++实现

// 插入排序
void insertionSort(vector<int>& array){
    // i 代表无序序列首元素(无序序列前为有序序列)
    size_t i = 1;
    while (i < array.size()){
        size_t j = i - 1;
        int itermToInsert = array[i];
        while (j >= 0){
            if (array[j] >= itermToInsert){
                array[j + 1] = array[j];
                j--;
            }
            else{
                break;
            }
        }
        array[j + 1] = itermToInsert;
        i++;
    }
}

2 Java实现

	public static int[] insertSort(int[] array){
		if(array.length > 0){			
			for(int i = 0 ;i<array.length - 1;i++){
				int current = array[i+1];
				int index = i;
				while(index >= 0 && current < array[index]){
					array[index + 1] = array[index]; 
					index--;
				}
				array[index+1] = current;
			}
			
		}
		return array;
	}

四 希尔排序

  • 一种插入排序,缩小增量排序
  • 希腊增量Java实现
  • 从小到大
  • 选择增量gap=length/2,缩小增量继续以gap = gap/2的方式,这种增量选择我们可以用一个序列来表示,{n/2,(n/2)/2…1},称为增量序列
  • 假设一共10个数,第一次10/2分为5组,第二次5/2分为2组,第三次2/2为1组,最后再进行简单的微调

1 c++实现

// 希尔排序
void shellSort(vector<int>& array){
    int n = array.size();
    for (int gap = n / 2; gap >= 1; gap /= 2){
        for (int i = gap; i < n; i++){
            // 使用插入排序算法,将元素依次插入所在小组的已排序列表中
            // 待插入元素
            int itermToInsert = array[i];
            int j = i - gap;
            while (j >= 0 && array[j] >= itermToInsert){
                array[j + gap] = array[j];
                j -= gap;
            }
            array[j + gap] = itermToInsert;
        }
    }
}

2 Java实现

public static int[] shellSort(int[] array){
    
        if(array.length > 0){    
            int len = array.length;
            int gap = len / 2;
            while(gap > 0){
                for(int i = gap;i < len;i++){
                    int temp = array[i];
                    int index = i - gap;
                    while(index >= 0 && array[index] > temp){
                        array[index + gap] = array[index];
                        index -= gap;
                    }
                    array[index + gap] = temp;
                }            
                gap /= 2;
            }
        }
        return array;
    }    

五 归并排序

  • 分治法
  • 把长度为n的输入序列分成两个长度为n/2的子序列,对这两个子序列分别采用归并排序,将两个排序好的子序列合并成一个最终的排序序列

1 c++实现

// 归并排序
// 合并两有序序列,两序列分别为array的0到mid部分和mid+1到末尾部分。
void merge(vector<int>& array, vector<int>& copyArray, int left, int right) {
	int mid = (left + right) / 2;
	int i = left, j = mid + 1, k = 0;
	while (i <= mid || j <= right) {
		if (i > mid) {
			copyArray[k] = array[j];
			j++;
		}
		else if (j > right) {
			copyArray[k] = array[i];
			i++;
		}
		else if (array[i] > array[j]) {
			copyArray[k] = array[j];
			j++;
		}
		else {
			copyArray[k] = array[i];
			i++;
		}

		k++;
	}

	for (size_t i = left; i <= right; i++) {
		array[i] = copyArray[i - left];
	}

}
void mergeSortHelp(vector<int>& array, vector<int>& copyArray, int left, int right) {
	if (left < right) {
		int mid = (left + right) / 2;
		mergeSortHelp(array, copyArray, left, mid);
		mergeSortHelp(array, copyArray, mid + 1, right);
		merge(array, copyArray, left, right);
	}
}
// 归并排序 递归实现
void mergeSort(vector<int>& array) {
	vector<int> copyArray(array);
	mergeSortHelp(array, copyArray, 0, array.size() - 1);
}

2 Java实现

	public static int[] MergeSort(int[] array){
		if(array.length < 2){
			return array;
		}
		int mid = array.length /2;
		int[] left = Arrays.copyOfRange(array, 0, mid);
		int[] right = Arrays.copyOfRange(array, mid, array.length);
		return merge(MergeSort(left),MergeSort(right));	
	}
	
	public static int[] merge(int[] left,int[] right){
		int[] result = new int[left.length + right.length];
		for(int index = 0,i = 0, j = 0;index < result.length;index++){
			if(i >= left.length){
				result[index] = right[j++];
			}else if(j >= right.length){
				result[index] = left[i++];
			}else if(left[i] > right[j]){
				result[index] = right[j++];
			}else{
				result[index] = left[i++];
			}
		}
		return result;	
	}

六 快速排序

  • 通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序
  • 从数列中挑出一个元素,称为 “基准”(pivot);
  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
  • 从小到大

1 c++实现

// 快速排序(递归)
// 选则最左端、最右端和中间位置3元素的中值作为基准值,并将3元素排序,返回基准值
int medianPovit(vector<int>& array, int left, int mid, int right){
    if (array[left] > array[mid]){
        swap(array[mid], array[left]);
    }
    if (array[left] > array[right]){
        swap(array[left], array[right]);
    }
    if (array[mid] > array[right]){
        swap(array[mid], array[right]);
    }
    return array[mid];
}
// 分区,返回基准索引
int partition(vector<int>& array, int left, int right) {
    // 中间位置索引
    int mid = (left + right) / 2;
    // 基准值(此时基准值对应索引为mid)
    int povit = medianPovit(array, left, mid, right);
    // 将基准值与倒数第二个元素交换
    array[mid] = array[right - 1];
    array[right - 1] = povit;

    int i = left, j = right - 1;
    while (i < j) {
        if (array[i] < povit) {
            i++;
        }
        else if (array[j] >= povit) {
            j--;
        }
        else {
            swap(array[i], array[j]);
        }
    }
    // 交换基准值和i位置元素
    swap(array[i], array[right - 1]);
    return i;
}
void quickSortHelp(vector<int>& array, int left, int right) {
    if (left < right) {
        int pivotLoction = partition(array, left, right);
        quickSortHelp(array, left, pivotLoction - 1);
        quickSortHelp(array, pivotLoction + 1, right);
    }
}
// 快速排序
void quickSort(vector<int>& array) {
    quickSortHelp(array, 0, array.size() - 1);
}

2 Java实现

	public static void QuickSort(int[] array,int low,int hight){
	//if (array.length < 1 || low < 0 || hight >= array.length || low > hight) return null;
		if(low < hight){
			int privotpos = partition(array,low,hight);
			QuickSort(array,low,privotpos - 1);
			QuickSort(array,privotpos + 1,hight);			
		}
	
	}
	
	public static int partition(int[] array,int low,int hight){
		int privot = array[low];
		while(low < hight){
			while(low < hight && array[hight] >= privot) --hight;
			array[low] = array[hight];
			while(low < hight && array[low] <= privot) ++low;
			array[hight] = array[low];
		}
		array[low] = privot;
		return low;			
	}

七 堆排序 Heap Sort

  • 堆:可以被看做一棵完全二叉树的数组对象
  • 将待排序列构造成一个大顶堆(或小顶堆),整个序列的最大值(或最小值)就是堆顶的根结点,将根节点的值和堆数组的末尾元素交换,此时末尾元素就是最大值(或最小值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次大值(或次小值),如此反复执行,最终得到一个有序序列
  • 满二叉树:一棵深度为k且有2k次方-1个结点的二叉树
  • 完全二叉树:如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同
在这里插入代码片// 堆排序
// 调整堆,根元素沿树向下移动,直至其合适位置,first和last分别为堆顶和堆底在数组array中的索引
void moveDown(vector<int>& array, int first, int last){
    // first的左子节点索引
    int curIndex = first * 2 + 1;
    while (curIndex <= last){
        // 若first有2子节点,令curIndex为其值最大子节点索引
        if (curIndex < last && array[curIndex] < array[curIndex + 1]){
            curIndex++;
        }
        // 若根节点值小于子节点值,则交换
        if (array[first] < array[curIndex]){
            swap(array[first], array[curIndex]);
            first = curIndex;
            curIndex = first * 2 + 1;
        }
        else{
            break;
        }
    }
}
// 用数组实现堆
void buildHeap(vector<int>& array){
    // 最后一个非叶节点的节点索引
    int i = array.size() / 2 - 1;
    while (i >= 0){
        moveDown(array, i, array.size() - 1);
        i--;
    }
}
// 堆排序
void heapSort(vector<int>& array){
    // 生成堆
    buildHeap(array);
    // 堆顶、底索引
    int first = 0, last = array.size() - 1;
    while (first <= last){
        swap(array[first], array[last]);
        last--;
        moveDown(array, first, last);
    }
}

2 Java实现

public static int[] heapSort(int[] array){
		int len = array.length;
		//初始化堆,构造一个最大堆
		for(int i = (len/2 - 1);i >= 0;i--){
			heapAdjust(array,i,len);
		}
		//将堆顶的元素和最后一个元素交换,并重新调整堆
		for(int i = len - 1;i > 0;i--){
			int temp = array[i];
			array[i] = array[0];
			array[0] = temp;
			
			heapAdjust(array,0,i);
		}
		return array;
	}

八 计数排序

  • 将输入的数据值转化为键存储在额外开辟的数组空间中

1 c++实现

// 计数排序
void countSort(vector<int>& array){
    if (array.empty()){
        return;
    }
    //找出最大最小值
    int min = array.front(),max = array.front();
    for (int i = 1; i < array.size(); i++){
        if (min > array[i]){
            min = array[i];
        }
        else if (max < array[i]){
            max = array[i];
        }
    }

    // 记录各元素出现次数
    vector<int> counts(max - min + 1);
    for (int i = 0; i < array.size(); i++){
        counts[array[i] - min]++;
    }

    // 根据记录的次数输出对应元素
    int index = 0;
    for (int j = 0; j < counts.size(); j++){
        int n = counts[j];
        while (n--){
            array[index] = j + min;
            index++;
        }
    }
}

2 Java实现

九 桶排序

1 c++实现

// 桶排序
void bucketSort (vector<int>& array, int bucketCount){
    if (array.empty()){
        return;
    }
    // 找出最大最小值
    int max = array.front(), min = array.front();
    for (int i = 1; i < array.size(); i++){
        if (min > array[i]){
            min = array[i];
        }
        else if (max < array[i]){
            max = array[i];
        }
    }

    // 将待排序的各元素分入对应桶中
    vector<vector<int>> buckets(bucketCount);
    int bucketSize = ceil((double)(max - min + 1) / bucketCount);
    for (int i = 0; i < array.size(); i++){
        int bucketIndex = (array[i] - min) / bucketSize;
        buckets[bucketIndex].push_back(array[i]);
    }

    // 对各桶中元素进行选择排序
    int index = 0;
    for (vector<int> bucket : buckets){
        if (!bucket.empty()){
            // 使用选择排序算法对桶内元素进行排序
            selectSort(bucket);
            for (int value : bucket){
                array[index] = value;
                index++;
            }
        }
    }

}
// 桶排序
void bucketSort (vector<int>& array){
    bucketSort (array, array.size() / 2);
}

2 Java实现

十 基数排序

1 c++实现

// 基数排序 (只适用于正数,此处不适用)
void radixSort(vector<int>& array){
    // 当前位数
    int curdigit = 10;
    // 当前位是否已超过最高为
    bool isOverHighest = false;
    while (!isOverHighest){
        isOverHighest = true;
        // 利用分桶的思想来实现按各位进行排序
        vector<vector<int>> buckets(10);
        for (int curVal : array){
            int bucketIndex = curVal % curdigit - curVal % (curdigit / 10);
            buckets[bucketIndex].push_back(curVal);
            if (isOverHighest && curVal / curdigit){
                isOverHighest = false;
            }
        }
        // 按照桶的顺序,将各桶内元素拼接起来
        int index = 0;
        for (vector<int> bucket : buckets){
            for (int value : bucket){
                array[index] = value;
                index++;
            }
        }
        curdigit *= 10;
    }
}

2 Java实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值