1、冒泡排序
需要比较n-1次,每次从下到上比较,如果大于就交换,每一次确定一个最小的数在最上面,优化就是如果没有发生交换说明已经有序,就停止
元素比较的次数为:
(N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)(N-1)/2=N^2/2-N/2;
元素交换的次数为:
(N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)(N-1)/2=N^2/2-N/2;
总执行次数为:
(N2/2-N/2)+(N2/2-N/2)=N^2-N;
按照大O推导法则,保留函数中的最高阶项那么最终冒泡排序的时间复杂度为O(N^2).
public class maopao {
public static void main(String[] args) {
int[] arr = new int[8];
arr = new int[]{3, 9, -1, 10, 20, 30, 40, 50};
int n = arr.length-1;
//冒泡排序就是两两比较相邻的记录如果逆序,就交换
for (int i = 0; i < n-1;i++){
boolean flag = false;
for (int j = n-1 ; j >=i ; j--){
if (arr[j] > arr[j+1]){
swap2(arr,j,j+1);
flag = true;
}
}
if (!flag){
break;
}else {
flag = false;
}
}
for (int values : arr) {
System.out.print(values + " ");
}
}
public static void swap2(int[] arr,int i ,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
1、选择排序
public class xuanze {
public static void main(String[] args) {
int[] arr = new int[] {3, 9, -1, 10, 20, 30, 40, 50};
fangfa(arr);
for (int i : arr) {
System.out.print(i + " ");
}
}
public static void fangfa(int[] arr){
int min;
int n = arr.length;
for (int i = 0 ; i < n - 1 ; i ++){
min = i;
for(int j = i+1 ; j < n;j++){
if (arr[min] > arr[j]){
min = j;
}
}
if (min != i){ //索引发生变化
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
}
}
2、直接插入排序
排序原理:
1.把所有的元素分为两组,已经排序的和未排序的;
2.找到未排序的组中的第一个元素,向已经排序的组中进行插入;
3.倒叙遍历已经排序的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么就把待
插入元素放到这个位置,其他的元素向后移动一位;
public class charu {
public static void main(String[] args) {
int[] arr = {3,4,6,1,8,4,7,5};
sort(arr);
print(arr);
}
public static void sort(int[] arr ){
for (int i = 1;i< arr.length;i++){
for (int j = i;j > 0;j--){
if (arr[j] < arr[j-1]){
swap(arr,j,j-1);
}
}
}
}
public static void swap(int[] arr,int i ,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void print(int[] arr){
for (int i : arr) {
System.out.print(i+" ");
}
}
}
3、堆排序
public class heapRank {
public static void main(String[] args) {
int tree[]={4,10,3,5,1,2,6,8,9,7};
int n = tree.length;
heapsort(tree,n);
for (int i = 0; i < n; i++) {
System.out.print(tree[i] + " ");
}
}
public static void heapsort(int tree[],int n){
buidheap(tree,n);
for (int i =n-1;i>=0;i--){
swap(tree,i,0);
heapify(tree,i,0);
}
}
public static void buidheap(int tree[],int n){
int last_node = n-1;
int parent = (last_node-1)/2;
for (int i = parent ; i>=0; i--) {
heapify(tree,n,i);
}
}
public static void heapify(int tree[],int n,int i){
if (i >= n){
return;
}
int c1 = 2 * i + 1;
int c2 = 2 * i + 2;
int max = i;
if (c1<n && tree[c1] > tree[max]){
max = c1;
}
if (c2 <n && tree[c2] > tree[max]){
max = c2;
}
if (i != max){
swap(tree,i,max);
heapify(tree,n,max);
}
//为什么放在这里会栈溢出呢?、????,max-i-max 退不出来了
}
public static void swap(int arr[] ,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
4、快速排序
public class kuaisu {
public static void main(String[] args) {
int[] arr = {50,10,90,30,70,40,80,60,90};
int left = 0;
int right = arr.length - 1 ;
sort(arr,left,right);
for (int i : arr) {
System.out.print(i + " ");
}
}
public static void sort(int[] arr ,int left , int right){
int provit;
if (left < right){
provit = Partition(arr,left,right);
sort(arr, left,provit-1);
sort(arr,provit+1,right);
}
}
private static int Partition(int[] arr, int left, int right) {
int provietkey = arr[left];
while (left <right){
while (left<right && arr[right]>=provietkey){
right--;
}
arr[left] =arr[right];
while (left<right && arr[left]<=provietkey){
left++;
}
arr[right] =arr[left];
}
//跳出循环时right = left 把选取的这个数放在中间
arr[left] = provietkey;
return left;
}
}
5、归并排序
public class guibin {
public static void main(String[] args) {
int[] arr = {8,4,5,7,1,3,4,2};
int[] temp = new int[arr.length];
int left = 0;
int right = arr.length-1;
sort(arr,left,right,temp);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr, int left ,int right,int[] temp){
while (left < right){
int mid = (left + right)/2;
sort(arr,left,mid,temp);
sort(arr,mid+1,right,temp);
mergeSort( arr,left, mid, right, temp);
}
}
public static void mergeSort(int[] arr,int left,int mid,int right, int[] temp){
//左右两边的有序数列直到有一边处理完为止
//如果左边的小于右边的,就把左边的放到临时数组,贩子依然
int i = left;
int j = mid +1;
int t = 0;
while (i<= mid && j <= right ){
if (arr[i] <= arr[j]){
temp[t++] = arr[i++];
} else {
temp[t++] = arr[j++];
}
}
//当有一边处理完之后,把剩余的有序数组直接拷贝到临时数组
while (i<=mid){
temp[t++] = arr[i++];
}
while (j<=right){
temp[t++] = arr[j++];
}
//把临时数组拷贝到原数组,并不是每次都拷贝所有,第一次是left=0 right =1 ,第二次是 left =2,right=3
t = 0;
int templeft = left;
while (templeft <=right){
arr[templeft] = temp[t];
t++;
templeft++ ;
}
}
}
6、希尔排序
public class xier {
public static void main(String[] args) {
int[] arr = {8,9,1,7,2,3,5,4,6,0};
shellsort(arr);
System.out.println(Arrays.toString(arr));
}
public static void shellsort(int[] arr){
for(int gap = arr.length /2; gap > 0 ; gap = gap/2){
for (int i = gap ; i < arr.length ; i++){
for (int j = i-gap;j >= 0 ;j = j - gap){//莫名其妙
if (arr[j] > arr[j+gap]){
int temp = arr[j+gap];
arr[j+gap] = arr[j];
arr[j] = temp;
}
}
}
}
}
}