1.常用的八個(gè)基本排序算法
-前言:希爾排序和直接插入排序?qū)儆诓迦肱判蛩惴ㄖ盏伲?jiǎn)單選擇排序和堆排序?qū)儆谶x擇排序案糙,冒泡和快速排序?qū)儆诮粨Q排序,如下圖所示
1)直接插入排序
(1)基本思想:在要排序的一組數(shù)中,假設(shè)前面(n-1)[n>=2] 個(gè)數(shù)已經(jīng)是排好順序的奥吩,現(xiàn)在要把第n 個(gè)數(shù)插到前面的有序數(shù)中,使得這n個(gè)數(shù)也是排好順序的蕊梧。如此反復(fù)循環(huán)霞赫,直到全部排好順序。
(2)例子
(3)簡(jiǎn)單的代碼實(shí)現(xiàn)
package eight;
public class IndexSort {
public void insertSort(){
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
int temp=0;
for(int i=1;i<a.length;i++){
int j=i-1;
temp=a[i];
for(;j>=0&&temp<a[j];j--){
a[j+1]=a[j]; //將大于temp 的值整體后移一個(gè)單位
}
a[j+1]=temp;
}
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
}
}
2)希爾排序
(1)基本思想:算法先將要排序的一組數(shù)按某個(gè)增量 d(n/2,n為要排序數(shù)的個(gè)數(shù))分成若干組肥矢,每組中記錄的下標(biāo)相差 d.對(duì)每組中全部元素進(jìn)行直接插入排序端衰,然后再用一個(gè)較小的增量(d/2)對(duì)它進(jìn)行分組,在每組中再進(jìn)行直接插入排序甘改。當(dāng)增量減到 1 時(shí)旅东,進(jìn)行直接插入排序后,排序完成十艾。
(2)例子(待做)
(3)簡(jiǎn)單的代碼實(shí)現(xiàn)
package eight;
public class ShellSort {
public void shellSort(){
int a[]={1,54,6,3,78,34,12,45,56,100};
double d1=a.length;
int temp=0;
while(true){
d1= Math.ceil(d1/2);
int d=(int) d1;
for(int x=0;x<d;x++){
for(int i=x+d;i<a.length;i+=d){
int j=i-d;
temp=a[i];
for(;j>=0&&temp<a[j];j-=d){
a[j+d]=a[j];
}
a[j+d]=temp;
}
}
if(d==1){
break;
}
}
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
}
}
3)簡(jiǎn)單選擇排序
(1)基本思想:在要排序的一組數(shù)中抵代,選出最小的一個(gè)數(shù)與第一個(gè)位置的數(shù)交換;然后在剩下的數(shù)當(dāng)中再找最小的與第二個(gè)位置的數(shù)交換忘嫉,如此循環(huán)到倒數(shù)第二個(gè)數(shù)最后一個(gè)數(shù)比較為止荤牍。
(2)例子(待做)
(3)
package eight;
public class SelectSort {
public void selectSort(){
int a[]={1,54,6,3,78,34,12,45};
int position=0;
for(int i=0;i<a.length;i++){
int j=i+1;
position=i;
int temp=a[i];
for(;j<a.length;j++){
if(a[j]<temp){
temp=a[j];
position=j;
}
}
a[position]=a[i];
a[i]=temp;
}
for(int i=0;i<a.length;i++) {
System.out.println(a[i]);
}
}
}
4)堆排序
(1)基本思想:堆排序是一種樹形選擇排序,是對(duì)直接選擇排序的有效改進(jìn)庆冕。 由堆定義可以看出康吵,堆頂元素(即第一個(gè)元素)必為最大項(xiàng)(大頂堆)。完全二叉樹可以很直觀地表示堆的結(jié)構(gòu)访递。堆頂為根晦嵌,其它為左子樹、右子樹。初始時(shí)把要排序的數(shù)的序列看作是一棵順序存儲(chǔ)的二叉樹耍铜,調(diào)整它們的存儲(chǔ)序邑闺,使之成為一個(gè)堆,這時(shí)堆的根節(jié)點(diǎn)的數(shù)最大棕兼。然后將根節(jié)點(diǎn)與堆的最后一個(gè)節(jié)點(diǎn)交換陡舅。然后對(duì)前面(n-1)個(gè)數(shù)重新調(diào)整使之成為堆。依此類推伴挚,直到只有兩個(gè)節(jié)點(diǎn)的堆靶衍,并對(duì)它們作交換,最后得到有 n個(gè)節(jié)點(diǎn)的有序序列茎芋。從算法描述來看颅眶,堆排序需要兩個(gè)過程,一是建立堆田弥,二是堆頂與堆的最后一個(gè)元素交換位置涛酗。所以堆排序有兩個(gè)函數(shù)組成。一是建堆的滲透函數(shù)偷厦,二是反復(fù)調(diào)用滲透函數(shù)實(shí)現(xiàn)排序的函數(shù)商叹。
(3)簡(jiǎn)單代碼實(shí)現(xiàn)
package eight;
import java.util.Arrays;
public class HeapSort {
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
public void HeapSort(){
heapSort(a);
}
public void heapSort(int[] a){
System.out.println("開始排序");
int arrayLength=a.length; //循環(huán)建堆
for(int i=0;i<arrayLength-1;i++){ //建堆
buildMaxHeap(a,arrayLength-1-i); //交換堆頂和最后一個(gè)元素
swap(a,0,arrayLength-1-i);
System.out.println(Arrays.toString(a));
}
}
private void swap(int[] data, int i, int j) {
int tmp=data[i];
data[i]=data[j];
data[j]=tmp;
} //對(duì)data 數(shù)組從0到lastIndex 建大頂堆
private void buildMaxHeap(int[] data, int lastIndex) {
//從lastIndex 處節(jié)點(diǎn)(最后一個(gè)節(jié)點(diǎn))的父節(jié)點(diǎn)開始
for(int i=(lastIndex-1)/2;i>=0;i--){
int k=i;
while(k*2+1<=lastIndex){
//k 節(jié)點(diǎn)的左子節(jié)點(diǎn)的索引
int biggerIndex=2*k+1;
//如果biggerIndex 小于lastIndex,即biggerIndex+1 代表的k 節(jié)點(diǎn)的右子節(jié)點(diǎn)存在
if(biggerIndex<lastIndex){
//若果右子節(jié)點(diǎn)的值較大
if(data[biggerIndex]<data[biggerIndex+1]){
//biggerIndex 總是記錄較大子節(jié)點(diǎn)的索引
biggerIndex++;
}
}
if(data[k]<data[biggerIndex]){
swap(data,k,biggerIndex);
//將biggerIndex 賦予k只泼,開始while 循環(huán)的下一次循環(huán)剖笙,重新保證k節(jié)點(diǎn)的值大于其左右子節(jié)點(diǎn)的值
k=biggerIndex;
}else{
break;
}
}
}
}
}
5)冒泡排序
6)快速排序
7)歸并排序
8)基數(shù)排序
二叉樹算法
(1)平衡二叉樹
算法相關(guān)面試題
- 定義一個(gè)int型的一維數(shù)組,包含10個(gè)元素请唱,分別賦一些隨機(jī)整數(shù)弥咪,然后求出所有元素的最大值,最小值十绑,平均值聚至,和值,并輸出出來孽惰。
- 題目:輸入兩個(gè)正整數(shù)m和n晚岭,求其最大公約數(shù)和最小公倍數(shù)。