推荐文章:
数据结构与算法(java版):https://blog.csdn.net/zhankuangqu4845/article/details/86349087?utm_source=app
简介
算法(algorithm)是解决特定问题求解步骤的描述,在计算机中表现为有限的操作序列。在数据类型建立起来之后,就要对这些数据类型进行操作,建立起运算的集合即程序。运算的建立、方法好坏直接决定着计算机程序原型效率的高低。
(1)数据结构和算法的关系
两者基友联系又有区别。联系是程序=算法+数据结构。数据结构是算法实现的基础,算法总是要依赖某种数据结构来实现的。算法的操作对象是数据结构。区别是数据结构关注的是数据的逻辑结构、存储结构有一集基本操作,而算法更多的是关注如何在数据结构的基本上解决实际问题。算法是编程思想,数据结构则是这些思想的基础。
(2)算法的五大特性
有穷性,是指算法在执行有限的步骤之后,自动结束而不是出现无限循环,并且每一个步骤在可接受的时间内完成。
确定性,是指算法执行的每一步骤在一定条件下只有一条执行路径,也就是相同输入只能有一个唯一的输出结果。
可行性,是指算法每一步骤都必须可行,能够通过有限的执行次数完成。
输入,是指算法具有零个或多个输入。
输出,是指算法至少有一个或多个输出。
(3)算法设计要求:正确性、可读性、健壮性、高效率与低存储量需求。
十大排序算法:冒泡排序,选择排序,插入排序,希尔排序,堆排序,快速排序,归并排序,计数排序,桶排序和基数排序。
按稳定性划分(根据相同的值在排序之前和排序之后的前后位置是否不变来表示该排序算法是否稳定):
稳定:冒泡排序,插入排序,归并排序,计数排序,桶排序,基数排序
不稳定:选择排序,希尔排序,堆排序,快速排序
根据内外排划分(根据排序时所需数据是否一定要全部加载进内存来区分):
内排:冒泡排序,选择排序,插入排序,希尔排序,堆排序,快速排序
外排:归并排序,计数排序,桶排序,基数排序
图片转自网络
1、冒泡排序
泡排序的基本思想是:从第一位开始,两两相邻的数据比较,如果前面的数据比后面的数据大,则交换两个数据的位置,直到所有的数据有序。
public static void sort(int[] array) {
boolean flag = true;
for (int i = 0; i < array.length - 1 && flag; i++) {
flag = false;
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;
flag = true;
}
}
}
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
2、选择排序
选择排序的思想是:设排序序列的记录个数为n,进行n-1次选择,每次在n-i+1(i = 1,2,…,n-1)个记录中选择关键字最小的记录作为有效序列中的第i个记录。
public static void sort(int[] arr) {
int j;
for (int i = 1; i < arr.length; i++) {
int temp = arr[i];
j = i - 1;
while (j > -1 && temp < arr[j]) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
3、插入排序
插入排序的思想是:
⑴首先对数组的前两个数据进行从小到大的排序。
⑵接着将第3个数据与排好序的两个数据比较,将第3个数据插入合适的位置。
⑶然后,将第4个数据插入已排好序的前3个数据中。
⑷不断重复上述过程,直到把最后一个数据插入合适的位置。最后,便完成了对原始数组从小到大的排序。
private static int[] insertSort2(int[] arr) {
if (arr == null || arr.length < 2) {
return arr;
}
for (int i = 1; i < arr.length; i++) {
int temp = arr[i];
int indx = 0;
for (int j = i; j > 0; j--) {
if (arr[j] < arr[j - 1]) {
arr[j] = arr[j - 1];
indx = j - 1;
} else {
break;
}
arr[indx] = temp;
}
}
return arr;
}
4、快速排序
快速排序的思想是:通过基准数,将数组分成左右两个数组,左边都小于基准数,右边都大于基准数,然后左右两个数组继续分下去,直到所有数据都有序。
public static void quickSort(int[] arr,int low,int high){
int i,j,temp,t;
if(low>high){
return;
}
i=low;
j=high;
temp = arr[low];
while (i<j) {
while (temp<=arr[j]&&i<j) {
j--;
}
while (temp>=arr[i]&&i<j) {
i++;
}
if (i<j) {
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
arr[low] = arr[i];
arr[i] = temp;
quickSort(arr, low, j-1);
quickSort(arr, j+1, high);
}
5、堆排序
堆的定义:具有n个元素的序列(N1,N2,…,Nn),当且仅当满足(Ni>=N2i,Ni>=2i+1)或(Ni<=N2i,Ni<=2i+1)(i=1,2,…,N/2)时称之为堆。
堆排序的思想是:
建堆,
交换,从堆中踢出最大数,
剩余结点再建堆,再交换踢出最大数,
依次类推:最后堆中剩余的最后两个结点交换,踢出一个,排序完成。
public static void headSort(int[] arr) {
for (int i = (arr.length) / 2 - 1; i >= 0; i--) {
headAdjust(arr, arr.length, i);
}
for (int i = arr.length - 1; i >= 1; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
headAdjust(arr, i, 0);
}
}
private static void headAdjust(int[] arr, int len, int i) {
int k = i, temp = arr[i], index = 2 * k + 1;
while (index < len) {
if (index + 1 < len) {
if (arr[index] < arr[index + 1]) {
index = index + 1;
}
}
if (arr[index] > temp) {
arr[k] = arr[index];
k = index;
index = 2 * k + 1;
} else {
break;
}
}
list[k] = temp;
}
6、希尔排序
希尔排序的思想是:
设置increment(增量),把数组分成increment组,分别进行插入排序。然后,increment不断的减少,最终一定是increment=1,也就是整个数组进行插入排序,得出有序的序列。
public static void shellSort(int[] arr) {
int j = 0;
int temp = 0;
for (int increment = arr.length / 2; increment > 0; increment /= 2) {
System.out.println("increment:" + increment);
for (int i = increment; i < arr.length; i++) {
temp = arr[i];
for (j = i - increment; j >= 0; j -= increment) {
if (temp < arr[j]) {
arr[j + increment] = arr[j];
} else {
break;
}
}
arr[j + increment] = temp;
}
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
}
}
7、归并排序
归并排序的思想是:
归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
public static void sort(int[] data, int left, int right) {
if(left<right){
int center=(left+right)/2;
sort(data,left,center);
sort(data,center+1,right);
merge(data,left,center,right);
}
}
public static void merge(int[] arr, int left, int center, int right) {
int [] tmpArr=new int[arr.length];
int mid=center+1;
int third=left;
int tmp=left;
while(left<=center&&mid<=right){
if(arr[left]<=arr[mid]){
tmpArr[third++]=arr[left++];
}else{
tmpArr[third++]=arr[mid++];
}
}
while(mid<=right){
tmpArr[third++]=arr[mid++];
}
while(left<=center){
tmpArr[third++]=arr[left++];
}
while(tmp<=right){
arr[tmp]=tmpArr[tmp++];
}
System.out.println(Arrays.toString(arr));
}
8、基数排序
基数排序基本思想:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
public static void sort(int[] array) {
int max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
int time = 0;
while (max > 0) {
max /= 10;
time++;
}
List<ArrayList> queue = new ArrayList<ArrayList>();
for (int i = 0; i < 10; i++) {
ArrayList<Integer> queue1 = new ArrayList<Integer>();
queue.add(queue1);
}
for (int i = 0; i < time; i++) {
for (int j = 0; j < array.length; j++) {
int x = array[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
ArrayList<Integer> queue2 = queue.get(x);
queue2.add(array[j]);
queue.set(x, queue2);
}
int count = 0;// 元素计数器;
for (int k = 0; k < 10; k++) {
while (queue.get(k).size() > 0) {
ArrayList<Integer> queue3 = queue.get(k);
array[count] = queue3.get(0);
queue3.remove(0);
count++;
}
}
}
}