目錄:
- 算法簡介
- 排序算法
- 遞歸與窮舉
- 貪心與分治
- 動態(tài)規(guī)劃和回溯
1.算法簡介
解題方案的準確而完整的描述寄摆,是一系列解決問題的清晰指令婶恼。
特征
- 有窮性
- 確切性
- 輸入項
- 輸出項
- 可行性
算法優(yōu)劣評定
- 時間復雜度
- 空間復雜度
- 正確性
- 可讀性
- 健壯性
2.算法排序
2.1 插入排序
- 冒泡排序
public static void main(String [] args){
int[] a = {49,38,65,97,23,22,76,1,5,8,2,0,-1};
//直接插入排序開始
for(int i = 1;i<a.length;i++){
int temp = a[i];//新遍歷的值柏副,等待插入到前面的有序數(shù)組
int j;
for(j = i-1;j>=0;j--){
//將大于temp的數(shù)往后面移一步
if(a[j]>temp){
a[j+1] = a[j];
}else{
break;
}
}
//break數(shù)據(jù)代表j處數(shù)據(jù)小于temp割择,j之前的數(shù)據(jù)又是從小到大排列荔泳,所以temp就放在j后面
a[j+1] = temp;
}
System.out.println("排序后:");
for(int i = 0;i<a.length;i++){
System.out.println(" "+a[i]);
}
}
時間復雜度:O(N^2)
- 二分法排序
時間復雜度:O(logN)
- 希爾排序
時間復雜度:O(N^(3/2))
2.2 選擇排序
- 簡單選擇排序
時間復雜度:O(N^(3/2))
- 堆排序
//堆排序
public static void main(String[] args){
int[] array = {39,44,1,0,8,66,23,67,9,15,100,70,22,3,6,54};
HeapSort heapSort = new HeapSort();
heapSort.heapSort(array);
for(int i = 0;i<array.length;i++){
System.out.println(" "+array[i]);
}
}
public void heapSort(int [] a){
if(a == null||a.length<=1){
return;
}
//創(chuàng)建大堆
buildMaxHeap(a);
for(int i = a.length-1;i>=1;i--){
//最大元素已經(jīng)排在了下標為0的地方
exchangeElements(a, 0, i);//每交換換一次玛歌,就沉淀一個大元素
maxHeap(a, i, 0);
}
}
private void buildMaxHeap(int[] a) {
int half = (a.length -1)/2;//假設長度為9
for(int i = half;i>=0;i--){
//只需遍歷43210
maxHeap(a,a.length,i);
}
}
//length表示用于構造大堆的數(shù)組長度元素數(shù)量
private void maxHeap(int[] a, int length, int i) {
int left = i*2+1;
int right = i*2+2;
int largest = i;
if(left<length&&a[left]>a[i]){
largest = left;
}
if(right<length&&a[right]>a[largest]){
largest = right;
}
if(i!=largest){
//進行數(shù)據(jù)交換
exchangeElements(a,i,largest);
maxHeap(a, length, largest);
}
}
//在數(shù)組a里進行兩個下標元素交換
private void exchangeElements(int[] a, int i, int largest) {
int temp = a[i];
a[i] = a[largest];
a[largest] = temp;
}
時間復雜度:O(NlogN)
2.3 交換排序
- 快速排序
/**
* 快速排序
*
* @param a
* @param i
* @param j
*/
private void quickSort(int[] a, int low, int high) {
if (low < high) {
int middle = getMiddle(a, low, high);
quickSort(a, 0, middle - 1);
quickSort(a, middle + 1, high);
}
}
/**
* 獲取中間下標
*
* @param a
* @param low
* @param high
* @return
*/
private int getMiddle(int[] a, int low, int high) {
int temp = a[low];// 基準元素
while (low < high) {
while (low < high && a[high] >= temp) {
high--;
}
a[low] = a[high];
while (low < high && a[low] <= temp) {
low++;
}
a[high] = a[low];
}
a[low] = temp;// 插入到排序后正確的位置
return low;
}
public static void main(String[] args) {
QuickSort quickSort = new QuickSort();
int[] a = { 19, 2, 3, 90, 67, 33, -7, 24, 3, 56, 34, 5 };
quickSort.quickSort(a, 0, a.length - 1);
for (int num : a) {
System.out.println(" " + num);
}
}
時間復雜度:O(NlogN)
2.4 歸并排序
//歸并排序
public void mergeSort(int[] a, int left, int right) {
if (left < right) {
int middle = (left + right) / 2;
mergeSort(a, left, middle);
mergeSort(a, middle + 1, right);
merge(a, left, middle, right);// 合并
}
}
private void merge(int[] a, int left, int middle, int right) {
int[] tmpArray = new int[a.length];
int rightStart = middle + 1;
int tmp = left;
int third = left;
// 比較兩個小數(shù)組相應下標位置的數(shù)組大小达舒,小的先放進新數(shù)組
while (left <= middle && rightStart <= right) {
if (a[left] <= a[rightStart]) {
tmpArray[third++] = a[left++];
} else {
tmpArray[third++] = a[rightStart++];
}
}
// 如果左邊還有數(shù)據(jù)需要拷貝巩搏,把左邊數(shù)組剩下的拷貝到新數(shù)組
while (left <= middle) {
tmpArray[third++] = a[left++];
}
// 如果右邊還有數(shù)據(jù)......
while (rightStart <= right) {
tmpArray[third++] = a[rightStart++];
}
while (tmp <= right) {
a[tmp] = tmpArray[tmp++];
}
}
public static void main(String[] args) {
MergeSort mergeSort = new MergeSort();
int[] a = new int[] { 90, 3, 2, 67, 44, -9, 87, 65, 11, 9, 2, 8 };
mergeSort.mergeSort(a, 0, a.length - 1);
for (int n : a) {
System.out.print(" " + n);
}
}
時間復雜度:O(NlogN)
2.5 基數(shù)排序
public void sort(int[] array) {
int max = 0;// 獲取最大值
for (int i = 0; i < array.length; i++) {
if (max < array[i]) {
max = array[i];
}
}
int times = 0;// 獲取最大值位數(shù)
while (max > 0) {
max = max / 10;
times++;
}
List<ArrayList> queue = new ArrayList<ArrayList>();// 多維數(shù)組
for (int i = 0; i < 10; i++) {
ArrayList<Object> q = new ArrayList<>();
queue.add(q);
}
for (int i = 0; i < times; i++) {
for (int j = 0; j < array.length; j++) {
// 獲取對應的位的值(i為0是個位篙骡,1是10位丈甸,2是百位)
int x = array[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
ArrayList<Integer> q = queue.get(x);
q.add(array[j]);// 把元素添加進對應下標數(shù)組
// queue.set(x,q);//待定
}
// 開始收集
int count = 0;
for (int j = 0; j < 10; j++) {
while (queue.get(j).size() > 0) {
ArrayList<Integer> q = queue.get(j);// 拿到每一個數(shù)組
array[count] = q.get(0);
q.remove(0);
count++;
}
}
}
}
public static void main(String[] args) {
BasicSort basicSort = new BasicSort();
int[] a = { 136, 2, 6, 8, 9, 2, 8, 11, 23, 56, 34, 90, 89, 29, 145, 209, 320, 78, 3 };
basicSort.sort(a);
for (int n : a) {
System.out.print(" " + n);
}
}
時間復雜度:O(NlogN)
3.遞歸與窮舉
- 二分法查找