欢迎Star,本文的所有示例源码都在Github:https://github.com/AndroidHensen/Arithmetic
本篇内容包含
1、基本思想:
两个数比较大小,较大的数下沉,较小的数冒起来
2、实现步骤:
这张图就是将数字12,35,99,18,76竖起来
3、这张图模拟了冒泡排序的整个过程
1、程序优化:
2、实现口诀:
3、易犯错误:
#include
void bubbleSort(int arr[],int n){
int i,j,flag;
for (i = 1; i < n; i++) {
flag = 0;
for (j = 0; j < n-i; j++) {
if(arr[j]1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag =1;
}
}
if(flag == 0)break;
}
}
void main(){
int i;
int arr[10] = {1, 4, 8, 3, 2, 9, 5, 0, 7, 6};
bubbleSort(arr, 10);
//9,8,7,6,5,4,3,2,1,0,
for(i=0; i<10; i++){
printf("%d,", arr[i]);
}
}
public class BubbleSort {
public void bubbleSort(int[] arr,int n){
boolean flag;
for (int i = 1; i < n; i++) {
flag = false;
for (int j = 0; j < n-i; j++) {
if(arr[j]1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag =true;
}
}
if(!flag)break;
}
}
public static void main(String[] args) {
int[] arr = {1, 4, 8, 3, 2, 9, 5, 0, 7, 6};
BubbleSort sort = new BubbleSort();
sort.bubbleSort(arr, arr.length);
//9,8,7,6,5,4,3,2,1,0,
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+",");
}
}
}
1、我们从代码分析,可以知道有两个循环
2、那么就可以计算出各自复杂度
3、根据推导大O阶规则来进行推导
4、得到的冒泡排序的复杂度的大O表示法为
(1xn)+(n^2/2) ≈ n^2 = O(n^2)
1、基本思想:
2、实现步骤:
1、注意点:
2、实现口诀:
3、易犯错误:
#include
void selectSort(int arr[],int n){
int i,j,minIndex;
for (i = 0; i < n-1; i++) {
minIndex = i;
for (j = i+1; j < n; j++) {
if(arr[j]if(minIndex!=i){
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
}
void main(){
int i;
int arr[8] = {3, 1, 5, 7, 2, 4, 9, 6};
selectSort(arr, 8);
//1,2,3,4,5,6,7,9,
for(i=0; i<8; i++){
printf("%d,", arr[i]);
}
}
public class SelectSort {
public void selectSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
if (minIndex != i) {
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
}
public static void main(String[] args) {
int[] arr = {3, 1, 5, 7, 2, 4, 9, 6};
SelectSort sort = new SelectSort();
sort.selectSort(arr, arr.length);
//1,2,3,4,5,6,7,9,
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
1、我们从代码分析,可以知道有两个循环
2、那么就可以计算出各自复杂度
3、复杂度的大O表示法为
(4xn)+(1x(n^2/2)) ≈ n^2 = O(n^2)
1、基本思想:
2、实现步骤:
1、实现口诀:
2、易犯错误:
#include
void insertSort(int arr[],int n){
int i,j;
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j > 0; j--) {
if (arr[j] < arr[j - 1]) {
int temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
} else {
break;
}
}
}
}
void main(){
int i;
int arr[10] = {1, 4, 8, 3, 2, 9, 5, 0, 7, 6};
insertSort(arr, 10);
//0,1,2,3,4,5,6,7,8,9,
for(i=0; i<10; i++){
printf("%d,", arr[i]);
}
}
public class InsertSort {
public void insertSort(int[] arr, int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j > 0; j--) {
if (arr[j] < arr[j - 1]) {
int temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
} else {
break;
}
}
}
}
public static void main(String[] args) {
int[] arr = {1, 4, 8, 3, 2, 9, 5, 0, 7, 6};
InsertSort sort = new InsertSort();
sort.insertSort(arr, arr.length);
//0,1,2,3,4,5,6,7,8,9,
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
1、我们从代码分析,可以知道有两个循环
2、那么就可以计算出各自复杂度
3、复杂度的大O表示法为
(n)+(3x(n^2/2)) ≈ n^2 = O(n^2)
1、基本思想:
2、实现步骤:
这张图就是将数字9,1,2,5,7,4,8,6,3,5,按分量(数的个数/2)进行分组,然后在各分组中进行插入排序
1、实现口诀:
2、易犯错误:
#include
void shellSort(int arr[],int length){
int i,j,k;
int temp = 0;
int incre = length;
while(1){
incre = incre /2;
for (i=0;ifor (j=i+incre;j<length;j+=incre){
for (k=j;k>i;k-=incre){
if(arr[k]else{
break;
}
}
}
}
if(incre == 1){
break;
}
}
}
int main(){
int i;
int arr[10] = {3, 1, 5, 7, 2, 4, 9, 6, 8, 10};
shellSort(arr,10);
for (i = 0; i < 10; i++) {
printf("%d,",arr[i]);
}
}
public class ShellSort {
public void shellSort(int arr[],int length){
int temp = 0;
int incre = length;
while(true){
incre = incre /2;
//对分组进行遍历
for (int i=0;i//插入排序
for (int j=i+incre;jfor (int k=j;k>i;k-=incre){
if(arr[k]else{
break;
}
}
}
}
//无法分组,表示排序结束
if(incre == 1){
break;
}
}
}
public static void main(String[] args) {
int[] arr = {3, 1, 5, 7, 2, 4, 9, 6, 8, 10};
ShellSort sort = new ShellSort();
sort.shellSort(arr, arr.length);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
1、基本思想:
#include
/**
* 整理小顶堆,从i节点开始调整,从0开始计算,i节点的子节点为 2*i+1, 2*i+2
*
* @param a 所有节点
* @param i 第i个节点
* @param n 节点总数
*/
void MinHeapFixdown(int a[], int i, int n) {
int j = 2 * i + 1; //左节点
int temp = 0;
//j
while (j < n) {
//j+1
if (j + 1 < n && a[j + 1] < a[j]) {
//将节点移到右节点
j++;
}
//较大节点在下面
if (a[i] <= a[j])
break;
//较大节点在上面,则将大节点下移
temp = a[i];
a[i] = a[j];
a[j] = temp;
//复位
i = j;
j = 2 * i + 1;
}
}
//构建最小堆
void MakeMinHeap(int a[], int n) {
int i;
//从倒数第二层开始排序,取自己的孩子进行排序,这样所有的节点都排序到了
for (i = (n - 1) / 2; i >= 0; i--) {
MinHeapFixdown(a, i, n);
}
}
void MinHeap_Sort(int a[], int n) {
int i;
int temp = 0;
MakeMinHeap(a, n);
for (i = n - 1; i > 0; i--) {
temp = a[0];
a[0] = a[i];
a[i] = temp;
MinHeapFixdown(a, 0, i);
}
}
int main(){
int i;
int arr[10] = {1, 4, 8, 3, 2, 9, 5, 0, 7, 6};
MinHeap_Sort(arr,10);
for (i = 0; i < 10; i++) {
printf("%d,",arr[i]);
}
}
public class HeapSort {
public static void MinHeap_Sort(int a[], int n) {
int temp = 0;
MakeMinHeap(a, n);
for (int i = n - 1; i > 0; i--) {
temp = a[0];
a[0] = a[i];
a[i] = temp;
MinHeapFixdown(a, 0, i);
}
}
//构建最小堆
public static void MakeMinHeap(int a[], int n) {
//从倒数第二层开始排序,取自己的孩子进行排序,这样所有的节点都排序到了
for (int i = (n - 1) / 2; i >= 0; i--) {
MinHeapFixdown(a, i, n);
}
}
/**
* 整理小顶堆,从i节点开始调整,从0开始计算,i节点的子节点为 2*i+1, 2*i+2
*
* @param a 所有节点
* @param i 第i个节点
* @param n 节点总数
*/
public static void MinHeapFixdown(int a[], int i, int n) {
int j = 2 * i + 1; //左节点
int temp = 0;
//j
while (j < n) {
//j+1
if (j + 1 < n && a[j + 1] < a[j]) {
//将节点移到右节点
j++;
}
//较大节点在下面
if (a[i] <= a[j])
break;
//较大节点在上面,则将大节点下移
temp = a[i];
a[i] = a[j];
a[j] = temp;
//复位
i = j;
j = 2 * i + 1;
}
}
public static void main(String[] args) {
int[] arr = {1, 4, 8, 3, 2, 9, 5, 0, 7, 6};
MinHeap_Sort(arr, arr.length);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
1、基本思想:
#include
void quicksort(int a[],int left,int right)
{
int i,j,t,temp;
if(left>right)
return;
temp=a[left]; //存基准数
i=left;
j=right;
while(i!=j)
{
//先从右边开始找
while(a[j]>=temp && i//再从左边开始找
while(a[i]<=temp && i//交换两个数在数组中的位置
if(i//基准数归位
a[left]=a[i];
a[i]=temp;
quicksort(a,left,i-1);//继续处理左边的
quicksort(a,i+1,right);//继续处理右边的
}
int main()
{
int arr[10]= {1, 4, 8, 3, 2, 9, 5, 0, 7, 6};
int i;
quicksort(arr,1,10);
for (i = 0; i < 10; i++) {
printf("%d,",arr[i]);
}
return 0;
}
public class QuickSort {
public static void quicksort(int a[], int left, int right) {
int i, j, t, temp;
if (left > right)
return;
temp = a[left]; //存基准数
i = left;
j = right;
while (i != j) {
//先从右边开始找
while (a[j] >= temp && i < j)
j--;
//再从左边开始找
while (a[i] <= temp && i < j)
i++;
//交换两个数在数组中的位置
if (i < j) {
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
//基准数归位
a[left] = a[i];
a[i] = temp;
quicksort(a, left, i - 1);//继续处理左边的
quicksort(a, i + 1, right);//继续处理右边的
}
public static void main(String[] args) {
int arr[] = {1, 4, 8, 3, 2, 9, 5, 0, 7, 6};
quicksort(arr, 0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
1、基本思想:
public class MergeSort {
/**
* 归并排序
*
* @param a
* @param first
* @param last
* @param temp
*/
public void merge_sort(int a[], int first, int last, int temp[]) {
if (first < last) {
int middle = (first + last) / 2;
merge_sort(a, first, middle, temp);//左半部分排好序
merge_sort(a, middle + 1, last, temp);//右半部分排好序
mergeArray(a, first, middle, last, temp); //合并左右部分
}
}
/**
* 合并数组
*
* @param a
* @param first
* @param middle
* @param end
* @param temp
*/
public void mergeArray(int a[], int first, int middle, int end, int temp[]) {
int i = first;
int m = middle;
int j = middle + 1;
int n = end;
int k = 0;
while (i <= m && j <= n) {
//比较两个组的数
if (a[i] <= a[j]) {
temp[k] = a[i];
k++;
i++;
} else {
temp[k] = a[j];
k++;
j++;
}
}
//左边一组中,当左边分组被取完时,该把右边分组全部取出来
while (i <= m) {
temp[k] = a[i];
k++;
i++;
}
//右边一组中,当左边分组被取完时,该把右边分组全部取出来
while (j <= n) {
temp[k] = a[j];
k++;
j++;
}
//在temp中取出所有排序好的数
for (int ii = 0; ii < k; ii++) {
a[first + ii] = temp[ii];
}
}
public static void main(String[] args) {
int[] arr = {1, 4, 8, 3, 2, 9, 5, 0, 7, 6};
MergeSort sort = new MergeSort();
sort.merge_sort(arr, 0, arr.length - 1, new int[10]);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
在学习基数排序之前,必须要知道桶排序,所以先简单的学习一下桶排序
1、基本思想:
public class BucketSort {
public void sort(int[] keys, int bucketNum) {
int len = keys.length;
int[] bucket = new int[bucketNum];
//初始化每个桶
for (int i = 0; i < bucketNum; i++) {
bucket[i] = 0;
}
//为每个数添加到对应桶
for (int i = 0; i < len; i++) {
bucket[keys[i]]++;
}
//遍历数组,即为结果
for (int i = 0; i < bucketNum; i++) {
for (int j = 1; j <= bucket[i]; j++) {
System.out.print(i + ",");
}
}
}
public static void main(String[] args) {
int[] a = {1, 4, 8, 3, 2, 9, 5, 0, 7, 6, 9, 10, 9, 13, 14, 15, 11, 12, 17, 16, 19};
BucketSort sorter = new BucketSort();
sorter.sort(a, 20);
}
}
1、基本思想:
public class RadixSort {
/**
* @param arr 原数组
* @param temp 临时数组
* @param n 序列的数字个数
* @param k 最大的位数3
* @param r 基数10
* @param bin 桶中i位置存储的个数
*/
public void radixSort(int arr[], int temp[], int n, int k, int r, int bin[]) {
//digit:位数,个位、十位、百位等
for (int i = 0, digit = 1; i < k; i++, digit = digit * r) {
//初始化
for (int j = 0; j < r; j++) {
bin[j] = 0;
}
//计算每个箱子的数字个数
for (int j = 0; j < n; j++) {
bin[(arr[j] / digit) % r]++;
}
//bin[j]的个数修改为前j个箱子一共有几个数字
for (int j = 1; j < r; j++) {
bin[j] = bin[j - 1] + bin[j];
}
//取出每个
for (int j = n - 1; j >= 0; j--) { //重点理解
bin[(arr[j] / digit) % r]--;
temp[bin[(arr[j] / digit) % r]] = arr[j];
}
//将临时数组赋值给我们的数组
for (int j = 0; j < n; j++) {
arr[j] = temp[j];
}
}
}
public static void main(String[] args) {
int[] arr = {143, 454, 812, 343, 245, 913, 565, 12, 743, 632};
RadixSort sort = new RadixSort();
sort.radixSort(arr, new int[10], arr.length, 3, 10, new int[10]);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
排序类型 | 时间复杂度 |
---|---|
冒泡排序 | O(n^2) |
选择排序 | O(n^2) |
插入排序 | O(n^2) |
希尔排序 | O(n^1.5) |
堆排序 | O(N*logN) |
快速排序 | O(N*logN) |
归并排序 | O(N*logN) |
基数排序 | O(d(n+r)) |