㈠ java冒泡排序法代碼
冒泡排序是比較經典的排序演算法。代碼如下:
for(int i=1;i<arr.length;i++){
for(int j=1;j<arr.length-i;j++){
//交換位置
}
拓展資料:
原理:比較兩個相鄰的元素,將值大的元素交換至右端。
思路:依次比較相鄰的兩個數,將小數放在前面,大數放在後面。即在第一趟:首先比較第1個和第2個數,將小數放前,大數放後。然後比較第2個數和第3個數,將小數放前,大數放後,如此繼續,直至比較最後兩個數,將小數放前,大數放後。重復第一趟步驟,直至全部排序完成。
第一趟比較完成後,最後一個數一定是數組中最大的一個數,所以第二趟比較的時候最後一個數不參與比較;
第二趟比較完成後,倒數第二個數也一定是數組中第二大的數,所以第三趟比較的時候最後兩個數不參與比較;
依次類推,每一趟比較次數-1;
……
舉例說明:要排序數組:int[]arr={6,3,8,2,9,1};
for(int i=1;i<arr.length;i++){
for(int j=1;j<arr.length-i;j++){
//交換位置
}
㈡ java中的演算法,一共有多少種,哪幾種,怎麼分類。
就好比問,漢語中常用寫作方法有多少種,怎麼分類。
演算法按用途分,體現設計目的、有什麼特點
演算法按實現方式分,有遞歸、迭代、平行、序列、過程、確定、不確定等等
演算法按設計范型分,有分治、動態、貪心、線性、圖論、簡化等等
作為圖靈完備的語言,理論上」Java語言「可以實現所有演算法。
「Java的標准庫'中用了一些常用數據結構和相關演算法.
像apache common這樣的java庫中又提供了一些通用的演算法
㈢ 數據結構中比較各種排序演算法 求詳解 ,,,,,,,,,,
排序演算法包括:插入排序、交換排序、選擇排序以及合並排序。
其中插入排序包括直接插入排序和Shell排序,交換排序包括冒泡排序和分化交換排序,選擇排序包括直接選擇排序和堆排序。
這些排序演算法中,直接插入排序、冒泡排序和直接選擇排序這三種排序的演算法平均時間復雜度是O(n的平方);分化交換排序、堆排序和合並排序這三種排序的演算法平均時間復雜度是
㈣ 數據結構 java開發中常用的排序演算法有哪些
排序演算法有很多,所以在特定情景中使用哪一種演算法很重要。為了選擇合適的演算法,可以按照建議的順序考慮以下標准:
(1)執行時間
(2)存儲空間
(3)編程工作
對於數據量較小的情形,(1)(2)差別不大,主要考慮(3);而對於數據量大的,(1)為首要。
主要排序法有:
一、冒泡(Bubble)排序——相鄰交換
二、選擇排序——每次最小/大排在相應的位置
三、插入排序——將下一個插入已排好的序列中
四、殼(Shell)排序——縮小增量
五、歸並排序
六、快速排序
七、堆排序
八、拓撲排序
一、冒泡(Bubble)排序
----------------------------------Code 從小到大排序n個數------------------------------------
void BubbleSortArray()
{
for(int i=1;i<n;i++)
{
for(int j=0;i<n-i;j++)
{
if(a[j]>a[j+1])//比較交換相鄰元素
{
int temp;
temp=a[j]; a[j]=a[j+1]; a[j+1]=temp;
}
}
}
}
-------------------------------------------------Code------------------------------------------------
效率 O(n²),適用於排序小列表。
二、選擇排序
----------------------------------Code 從小到大排序n個數--------------------------------
void SelectSortArray()
{
int min_index;
for(int i=0;i<n-1;i++)
{
min_index=i;
for(int j=i+1;j<n;j++)//每次掃描選擇最小項
if(arr[j]<arr[min_index]) min_index=j;
if(min_index!=i)//找到最小項交換,即將這一項移到列表中的正確位置
{
int temp;
temp=arr[i]; arr[i]=arr[min_index]; arr[min_index]=temp;
}
}
}
-------------------------------------------------Code-----------------------------------------
效率O(n²),適用於排序小的列表。
三、插入排序
--------------------------------------------Code 從小到大排序n個數-------------------------------------
void InsertSortArray()
{
for(int i=1;i<n;i++)//循環從第二個數組元素開始,因為arr[0]作為最初已排序部分
{
int temp=arr[i];//temp標記為未排序第一個元素
int j=i-1;
while (j>=0 && arr[j]>temp)/*將temp與已排序元素從小到大比較,尋找temp應插入的位置*/
{
arr[j+1]=arr[j];
j--;
}
arr[j+1]=temp;
}
}
------------------------------Code--------------------------------------------------------------
最佳效率O(n);最糟效率O(n²)與冒泡、選擇相同,適用於排序小列表
若列表基本有序,則插入排序比冒泡、選擇更有效率。
四、殼(Shell)排序——縮小增量排序
-------------------------------------Code 從小到大排序n個數-------------------------------------
void ShellSortArray()
{
for(int incr=3;incr<0;incr--)//增量遞減,以增量3,2,1為例
{
for(int L=0;L<(n-1)/incr;L++)//重復分成的每個子列表
{
for(int i=L+incr;i<n;i+=incr)//對每個子列表應用插入排序
{
int temp=arr[i];
int j=i-incr;
while(j>=0&&arr[j]>temp)
{
arr[j+incr]=arr[j];
j-=incr;
}
arr[j+incr]=temp;
}
}
}
}
--------------------------------------Code-------------------------------------------
適用於排序小列表。
效率估計O(nlog2^n)~O(n^1.5),取決於增量值的最初大小。建議使用質數作為增量值,因為如果增量值是2的冪,則在下一個通道中會再次比較相同的元素。
殼(Shell)排序改進了插入排序,減少了比較的次數。是不穩定的排序,因為排序過程中元素可能會前後跳躍。
五、歸並排序
----------------------------------------------Code 從小到大排序---------------------------------------
void MergeSort(int low,int high)
{
if(low>=high) return;//每個子列表中剩下一個元素時停止
else int mid=(low+high)/2;/*將列表劃分成相等的兩個子列表,若有奇數個元素,則在左邊子列表大於右側子列表*/
MergeSort(low,mid);//子列表進一步劃分
MergeSort(mid+1,high);
int [] B=new int [high-low+1];//新建一個數組,用於存放歸並的元素
for(int i=low,j=mid+1,k=low;i<=mid && j<=high;k++)/*兩個子列表進行排序歸並,直到兩個子列表中的一個結束*/
{
if (arr[i]<=arr[j];)
{
B[k]=arr[i];
I++;
}
else
{ B[k]=arr[j]; j++; }
}
for( ;j<=high;j++,k++)//如果第二個子列表中仍然有元素,則追加到新列表
B[k]=arr[j];
for( ;i<=mid;i++,k++)//如果在第一個子列表中仍然有元素,則追加到新列表中
B[k]=arr[i];
for(int z=0;z<high-low+1;z++)//將排序的數組B的 所有元素復制到原始數組arr中
arr[z]=B[z];
}
-----------------------------------------------------Code---------------------------------------------------
效率O(nlogn),歸並的最佳、平均和最糟用例效率之間沒有差異。
適用於排序大列表,基於分治法。
六、快速排序
------------------------------------Code--------------------------------------------
/*快速排序的演算法思想:選定一個樞紐元素,對待排序序列進行分割,分割之後的序列一個部分小於樞紐元素,一個部分大於樞紐元素,再對這兩個分割好的子序列進行上述的過程。*/ void swap(int a,int b){int t;t =a ;a =b ;b =t ;}
int Partition(int [] arr,int low,int high)
{
int pivot=arr[low];//採用子序列的第一個元素作為樞紐元素
while (low < high)
{
//從後往前栽後半部分中尋找第一個小於樞紐元素的元素
while (low < high && arr[high] >= pivot)
{
--high;
}
//將這個比樞紐元素小的元素交換到前半部分
swap(arr[low], arr[high]);
//從前往後在前半部分中尋找第一個大於樞紐元素的元素
while (low <high &&arr [low ]<=pivot )
{
++low ;
}
swap (arr [low ],arr [high ]);//將這個樞紐元素大的元素交換到後半部分
}
return low ;//返回樞紐元素所在的位置
}
void QuickSort(int [] a,int low,int high)
{
if (low <high )
{
int n=Partition (a ,low ,high );
QuickSort (a ,low ,n );
QuickSort (a ,n +1,high );
}
}
----------------------------------------Code-------------------------------------
平均效率O(nlogn),適用於排序大列表。
此演算法的總時間取決於樞紐值的位置;選擇第一個元素作為樞紐,可能導致O(n²)的最糟用例效率。若數基本有序,效率反而最差。選項中間值作為樞紐,效率是O(nlogn)。
基於分治法。
七、堆排序
最大堆:後者任一非終端節點的關鍵字均大於或等於它的左、右孩子的關鍵字,此時位於堆頂的節點的關鍵字是整個序列中最大的。
思想:
(1)令i=l,並令temp= kl ;
(2)計算i的左孩子j=2i+1;
(3)若j<=n-1,則轉(4),否則轉(6);
(4)比較kj和kj+1,若kj+1>kj,則令j=j+1,否則j不變;
(5)比較temp和kj,若kj>temp,則令ki等於kj,並令i=j,j=2i+1,並轉(3),否則轉(6)
(6)令ki等於temp,結束。
-----------------------------------------Code---------------------------
void HeapSort(SeqIAst R)
{ //對R[1..n]進行堆排序,不妨用R[0]做暫存單元 int I; BuildHeap(R); //將R[1-n]建成初始堆for(i=n;i>1;i--) //對當前無序區R[1..i]進行堆排序,共做n-1趟。{ R[0]=R[1]; R[1]=R[i]; R[i]=R[0]; //將堆頂和堆中最後一個記錄交換 Heapify(R,1,i-1); //將R[1..i-1]重新調整為堆,僅有R[1]可能違反堆性質 } } ---------------------------------------Code--------------------------------------
堆排序的時間,主要由建立初始堆和反復重建堆這兩部分的時間開銷構成,它們均是通過調用Heapify實現的。
堆排序的最壞時間復雜度為O(nlgn)。堆排序的平均性能較接近於最壞性能。 由於建初始堆所需的比較次數較多,所以堆排序不適宜於記錄數較少的文件。 堆排序是就地排序,輔助空間為O(1), 它是不穩定的排序方法。
堆排序與直接插入排序的區別:
直接選擇排序中,為了從R[1..n]中選出關鍵字最小的記錄,必須進行n-1次比較,然後在R[2..n]中選出關鍵字最小的記錄,又需要做n-2次比較。事實上,後面的n-2次比較中,有許多比較可能在前面的n-1次比較中已經做過,但由於前一趟排序時未保留這些比較結果,所以後一趟排序時又重復執行了這些比較操作。
堆排序可通過樹形結構保存部分比較結果,可減少比較次數。
八、拓撲排序
例 :學生選修課排課先後順序
拓撲排序:把有向圖中各頂點按照它們相互之間的優先關系排列成一個線性序列的過程。
方法:
在有向圖中選一個沒有前驅的頂點且輸出
從圖中刪除該頂點和所有以它為尾的弧
重復上述兩步,直至全部頂點均已輸出(拓撲排序成功),或者當圖中不存在無前驅的頂點(圖中有迴路)為止。
---------------------------------------Code--------------------------------------
void TopologicalSort()/*輸出拓撲排序函數。若G無迴路,則輸出G的頂點的一個拓撲序列並返回OK,否則返回ERROR*/
{
int indegree[M];
int i,k,j;
char n;
int count=0;
Stack thestack;
FindInDegree(G,indegree);//對各頂點求入度indegree[0....num]
InitStack(thestack);//初始化棧
for(i=0;i<G.num;i++)
Console.WriteLine("結點"+G.vertices[i].data+"的入度為"+indegree[i]);
for(i=0;i<G.num;i++)
{
if(indegree[i]==0)
Push(thestack.vertices[i]);
}
Console.Write("拓撲排序輸出順序為:");
while(thestack.Peek()!=null)
{
Pop(thestack.Peek());
j=locatevex(G,n);
if (j==-2)
{
Console.WriteLine("發生錯誤,程序結束。");
exit();
}
Console.Write(G.vertices[j].data);
count++;
for(p=G.vertices[j].firstarc;p!=NULL;p=p.nextarc)
{
k=p.adjvex;
if (!(--indegree[k]))
Push(G.vertices[k]);
}
}
if (count<G.num)
Cosole.WriteLine("該圖有環,出現錯誤,無法排序。");
else
Console.WriteLine("排序成功。");
}
----------------------------------------Code--------------------------------------
演算法的時間復雜度O(n+e)。
㈤ java編程的冒泡等排序示例
Java排序演算法
1)分類:
1)插入排序(直接插入排序、希爾排序)
2)交換排序(冒泡排序、快速排序)
3)選擇排序(直接選擇排序、堆排序)
4)歸並排序
5)分配排序(箱排序、基數排序)
所需輔助空間最多:歸並排序
所需輔助空間最少:堆排序
平均速度最快:快速排序
不穩定:快速排序,希爾排序,堆排序。
1)選擇排序演算法的時候
1.數據的規模 ; 2.數據的類型 ; 3.數據已有的順序
一般來說,當數據規模較小時,應選擇直接插入排序或冒泡排序。任何排序演算法在數據量小時基本體現不出來差距。 考慮數據的類型,比如如果全部是正整數,那麼考慮使用桶排序為最優。 考慮數據已有順序,快排是一種不穩定的排序(當然可以改進),對於大部分排好的數據,快排會浪費大量不必要的步驟。數據量極小,而起已經基本排好序,冒泡是最佳選擇。我們說快排好,是指大量隨機數據下,快排效果最理想。而不是所有情況。
3)總結:
——按平均的時間性能來分:
1)時間復雜度為O(nlogn)的方法有:快速排序、堆排序和歸並排序,其中以快速排序為最好;
2)時間復雜度為O(n2)的有:直接插入排序、起泡排序和簡單選擇排序,其中以直接插入為最好,特 別是對那些對關鍵字近似有序的記錄序列尤為如此;
3)時間復雜度為O(n)的排序方法只有,基數排序。
當待排記錄序列按關鍵字順序有序時,直接插入排序和起泡排序能達到O(n)的時間復雜度;而對於快速排序而言,這是最不好的情況,此時的時間性能蛻化為O(n2),因此是應該盡量避免的情況。簡單選擇排序、堆排序和歸並排序的時間性能不隨記錄序列中關鍵字的分布而改變。
——按平均的空間性能來分(指的是排序過程中所需的輔助空間大小):
1) 所有的簡單排序方法(包括:直接插入、起泡和簡單選擇)和堆排序的空間復雜度為O(1);
2) 快速排序為O(logn ),為棧所需的輔助空間;
3) 歸並排序所需輔助空間最多,其空間復雜度為O(n );
4)鏈式基數排序需附設隊列首尾指針,則空間復雜度為O(rd )。
——排序方法的穩定性能:
1) 穩定的排序方法指的是,對於兩個關鍵字相等的記錄,它們在序列中的相對位置,在排序之前和 經過排序之後,沒有改變。
2) 當對多關鍵字的記錄序列進行LSD方法排序時,必須採用穩定的排序方法。
3) 對於不穩定的排序方法,只要能舉出一個實例說明即可。
4) 快速排序,希爾排序和堆排序是不穩定的排序方法。
4)插入排序:
包括直接插入排序,希爾插入排序。
直接插入排序: 將一個記錄插入到已經排序好的有序表中。
1, sorted數組的第0個位置沒有放數據。
2,從sorted第二個數據開始處理:
如果該數據比它前面的數據要小,說明該數據要往前面移動。
首先將該數據備份放到 sorted的第0位置當哨兵。
然後將該數據前面那個數據後移。
然後往前搜索,找插入位置。
找到插入位置之後講 第0位置的那個數據插入對應位置。
O(n*n), 當待排記錄序列為正序時,時間復雜度提高至O(n)。
希爾排序(縮小增量排序 diminishing increment sort):先將整個待排記錄序列分割成若干個子序列分別進行直接插入排序,待整個序列中的記錄基本有序時,再對全體記錄進行一次直接插入排序。
面試穿什麼,這里找答案!
插入排序Java代碼:
public class InsertionSort {
// 插入排序:直接插入排序 ,希爾排序
public void straightInsertionSort(double [] sorted){
int sortedLen= sorted.length;
for(int j=2;j<sortedLen;j++){
if(sorted[j]<sorted[j-1]){
sorted[0]= sorted[j];//先保存一下後面的那個
sorted[j]=sorted[j-1];// 前面的那個後移。
int insertPos=0;
for(int k=j-2;k>=0;k--){
if(sorted[k]>sorted[0]){
sorted[k+1]=sorted[k];
}else{
insertPos=k+1;
break;
}
}
sorted[insertPos]=sorted[0];
}
}
}
public void shellInertionSort(double [] sorted, int inc){
int sortedLen= sorted.length;
for(int j=inc+1;j<sortedLen;j++ ){
if(sorted[j]<sorted[j-inc]){
sorted[0]= sorted[j];//先保存一下後面的那個
int insertPos=j;
for(int k=j-inc;k>=0;k-=inc){
if(sorted[k]>sorted[0]){
sorted[k+inc]=sorted[k];
//數據結構課本上這個地方沒有給出判讀,出錯:
if(k-inc<=0){
insertPos = k;
}
}else{
insertPos=k+inc;
break;
}
}
sorted[insertPos]=sorted[0];
}
}
}
public void shellInsertionSort(double [] sorted){
int[] incs={7,5,3,1};
int num= incs.length;
int inc=0;
for(int j=0;j<num;j++){
inc= incs[j];
shellInertionSort(sorted,inc);
}
}
public static void main(String[] args) {
Random random= new Random(6);
int arraysize= 21;
double [] sorted=new double[arraysize];
System.out.print("Before Sort:");
for(int j=1;j<arraysize;j++){
sorted[j]= (int)(random.nextDouble()* 100);
System.out.print((int)sorted[j]+" ");
}
System.out.println();
InsertionSort sorter=new InsertionSort();
// sorter.straightInsertionSort(sorted);
sorter.shellInsertionSort(sorted);
System.out.print("After Sort:");
for(int j=1;j<sorted.length;j++){
System.out.print((int)sorted[j]+" ");
}
System.out.println();
}
}
面試穿什麼,這里找答案!
5)交換排序:
包括冒泡排序,快速排序。
冒泡排序法:該演算法是專門針對已部分排序的數據進行排序的一種排序演算法。如果在你的數據清單中只有一兩個數據是亂序的話,用這種演算法就是最快的排序演算法。如果你的數據清單中的數據是隨機排列的,那麼這種方法就成了最慢的演算法了。因此在使用這種演算法之前一定要慎重。這種演算法的核心思想是掃描數據清單,尋找出現亂序的兩個相鄰的項目。當找到這兩個項目後,交換項目的位置然後繼續掃描。重復上面的操作直到所有的項目都按順序排好。
快速排序:通過一趟排序,將待排序記錄分割成獨立的兩個部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。具體做法是:使用兩個指針low,high, 初值分別設置為序列的頭,和序列的尾,設置pivotkey為第一個記錄,首先從high開始向前搜索第一個小於pivotkey的記錄和pivotkey所在位置進行交換,然後從low開始向後搜索第一個大於pivotkey的記錄和此時pivotkey所在位置進行交換,重復知道low=high了為止。
交換排序Java代碼:
public class ExchangeSort {
public void BubbleExchangeSort(double [] sorted){
int sortedLen= sorted.length;
for(int j=sortedLen;j>0;j--){
int end= j;
for(int k=1;k<end-1;k++){
double tempB= sorted[k];
sorted[k]= sorted[k]<sorted[k+1]?
sorted[k]:sorted[k+1];
if(Math.abs(sorted[k]-tempB)>10e-6){
sorted[k+1]=tempB;
}
}
}
}
public void QuickExchangeSortBackTrack(double [] sorted,
int low,int high){
if(low<high){
int pivot= findPivot(sorted,low,high);
QuickExchangeSortBackTrack(sorted,low,pivot-1);
QuickExchangeSortBackTrack(sorted,pivot+1,high);
}
}
public int findPivot(double [] sorted, int low, int high){
sorted[0]= sorted[low];
while(low<high){
while(low<high && sorted[high]>= sorted[0])--high;
sorted[low]= sorted[high];
while(low<high && sorted[low]<=sorted[0])++low;
sorted[high]= sorted[low];
}
sorted[low]=sorted[0];
return low;
}
public static void main(String[] args) {
Random random= new Random(6);
int arraysize= 21;
double [] sorted=new double[arraysize];
System.out.print("Before Sort:");
for(int j=1;j<arraysize;j++){
sorted[j]= (int)(random.nextDouble()* 100);
System.out.print((int)sorted[j]+" ");
}
System.out.println();
ExchangeSort sorter=new ExchangeSort();
// sorter.BubbleExchangeSort(sorted);
sorter.QuickExchangeSortBackTrack(sorted, 1, arraysize-1);
System.out.print("After Sort:");
for(int j=1;j<sorted.length;j++){
System.out.print((int)sorted[j]+" ");
}
System.out.println();
}
}
6)選擇排序:
分為直接選擇排序, 堆排序
直接選擇排序:第i次選取 i到array.Length-1中間最小的值放在i位置。
堆排序:首先,數組裡面用層次遍歷的順序放一棵完全二叉樹。從最後一個非終端結點往前面調整,直到到達根結點,這個時候除根節點以外的所有非終端節點都已經滿足堆得條件了,於是需要調整根節點使得整個樹滿足堆得條件,於是從根節點開始,沿著它的兒子們往下面走(最大堆沿著最大的兒子走,最小堆沿著最小的兒子走)。 主程序裡面,首先從最後一個非終端節點開始調整到根也調整完,形成一個heap, 然後將heap的根放到後面去(即:每次的樹大小會變化,但是 root都是在1的位置,以方便計算兒子們的index,所以如果需要升序排列,則要逐步大頂堆。因為根節點被一個個放在後面去了。 降序排列則要建立小頂堆)
代碼中的問題: 有時候第2個和第3個順序不對(原因還沒搞明白到底代碼哪裡有錯)
選擇排序Java代碼:
public class SelectionSort {
public void straitSelectionSort(double [] sorted){
int sortedLen= sorted.length;
for(int j=1;j<sortedLen;j++){
int jMin= getMinIndex(sorted,j);
exchange(sorted,j,jMin);
}
}
public void exchange(double [] sorted,int i,int j){
int sortedLen= sorted.length;
if(i<sortedLen && j<sortedLen && i<j && i>=0 && j>=0){
double temp= sorted[i];
sorted[i]=sorted[j];
sorted[j]=temp;
}
}
public int getMinIndex(double [] sorted, int i){
int sortedLen= sorted.length;
int minJ=1;
double min= Double.MAX_VALUE;
for(int j=i;j<sortedLen;j++){
if(sorted[j]<min){
min= sorted[j];
minJ= j;
}
}
return minJ;
}
public void heapAdjust(double [] sorted,int start,int end){
if(start<end){
double temp= sorted[start];
// 這個地方j<end與課本不同,j<=end會報錯:
for(int j=2*start;j<end;j *=2){
if(j+1<end && sorted[j]-sorted[j+1]>10e-6){
++j;
}
if(temp<=sorted[j]){
break;
}
sorted[start]=sorted[j];
start=j;
}
sorted[start]=temp;
}
}
public void heapSelectionSort(double [] sorted){
int sortedLen = sorted.length;
for(int i=sortedLen/2;i>0;i--){
heapAdjust(sorted,i,sortedLen);
}
for(int i=sortedLen;i>1;--i){
exchange(sorted,1,i);
heapAdjust(sorted,1,i-1);
}
}
public static void main(String [] args){
Random random= new Random(6);
int arraysize=9;
double [] sorted=new double[arraysize];
System.out.print("Before Sort:");
for(int j=1;j<arraysize;j++){
sorted[j]= (int)(random.nextDouble()* 100);
System.out.print((int)sorted[j]+" ");
}
System.out.println();
SelectionSort sorter=new SelectionSort();
// sorter.straitSelectionSort(sorted);
sorter.heapSelectionSort(sorted);
System.out.print("After Sort:");
for(int j=1;j<sorted.length;j++){
System.out.print((int)sorted[j]+" ");
}
System.out.println();
}
}
面試穿什麼,這里找答案!
7)歸並排序:
將兩個或兩個以上的有序表組合成一個新的有序表。歸並排序要使用一個輔助數組,大小跟原數組相同,遞歸做法。每次將目標序列分解成兩個序列,分別排序兩個子序列之後,再將兩個排序好的子序列merge到一起。
歸並排序Java代碼:
public class MergeSort {
private double[] bridge;//輔助數組
public void sort(double[] obj){
if (obj == null){
throw new NullPointerException("
The param can not be null!");
}
bridge = new double[obj.length]; // 初始化中間數組
mergeSort(obj, 0, obj.length - 1); // 歸並排序
bridge = null;
}
private void mergeSort(double[] obj, int left, int right){
if (left < right){
int center = (left + right) / 2;
mergeSort(obj, left, center);
mergeSort(obj, center + 1, right);
merge(obj, left, center, right);
}
}
private void merge(double[] obj, int left,
int center, int right){
int mid = center + 1;
int third = left;
int tmp = left;
while (left <= center && mid <= right){
// 從兩個數組中取出小的放入中間數組
if (obj[left]-obj[mid]<=10e-6){
bridge[third++] = obj[left++];
} else{
bridge[third++] = obj[mid++];
}
}
// 剩餘部分依次置入中間數組
while (mid <= right){
bridge[third++] = obj[mid++];
}
while (left <= center){
bridge[third++] = obj[left++];
}
// 將中間數組的內容拷貝回原數組
(obj, tmp, right);
}
private void (double[] obj, int left, int right)
{
while (left <= right){
obj[left] = bridge[left];
left++;
}
}
public static void main(String[] args) {
Random random = new Random(6);
int arraysize = 10;
double[] sorted = new double[arraysize];
System.out.print("Before Sort:");
for (int j = 0; j < arraysize; j++) {
sorted[j] = (int) (random.nextDouble() * 100);
System.out.print((int) sorted[j] + " ");
}
System.out.println();
MergeSort sorter = new MergeSort();
sorter.sort(sorted);
System.out.print("After Sort:");
for (int j = 0; j < sorted.length; j++) {
System.out.print((int) sorted[j] + " ");
}
System.out.println();
}
}
面試穿什麼,這里找答案!
8)基數排序:
使用10個輔助隊列,假設最大數的數字位數為 x, 則一共做 x次,從個位數開始往前,以第i位數字的大小為依據,將數據放進輔助隊列,搞定之後回收。下次再以高一位開始的數字位為依據。
以Vector作輔助隊列,基數排序的Java代碼:
public class RadixSort {
private int keyNum=-1;
private Vector<Vector<Double>> util;
public void distribute(double [] sorted, int nth){
if(nth<=keyNum && nth>0){
util=new Vector<Vector<Double>>();
for(int j=0;j<10;j++){
Vector <Double> temp= new Vector <Double>();
util.add(temp);
}
for(int j=0;j<sorted.length;j++){
int index= getNthDigit(sorted[j],nth);
util.get(index).add(sorted[j]);
}
}
}
public int getNthDigit(double num,int nth){
String nn= Integer.toString((int)num);
int len= nn.length();
if(len>=nth){
return Character.getNumericValue(nn.charAt(len-nth));
}else{
return 0;
}
}
public void collect(double [] sorted){
int k=0;
for(int j=0;j<10;j++){
int len= util.get(j).size();
if(len>0){
for(int i=0;i<len;i++){
sorted[k++]= util.get(j).get(i);
}
}
}
util=null;
}
public int getKeyNum(double [] sorted){
double max= Double.MIN_VALUE;
for(int j=0;j<sorted.length;j++){
if(sorted[j]>max){
max= sorted[j];
}
}
return Integer.toString((int)max).length();
}
public void radixSort(double [] sorted){
if(keyNum==-1){
keyNum= getKeyNum(sorted);
}
for(int i=1;i<=keyNum;i++){
distribute(sorted,i);
collect(sorted);
}
}
public static void main(String[] args) {
Random random = new Random(6);
int arraysize = 21;
double[] sorted = new double[arraysize];
System.out.print("Before Sort:");
for (int j = 0; j < arraysize; j++) {
sorted[j] = (int) (random.nextDouble() * 100);
System.out.print((int) sorted[j] + " ");
}
System.out.println();
RadixSort sorter = new RadixSort();
sorter.radixSort(sorted);
System.out.print("After Sort:");
for (int j = 0; j < sorted.length; j++) {
System.out.print((int) sorted[j] + " ");
}
System.out.println();
}
}
//而來
㈥ 《數據結構與演算法分析Java語言描述(英文版·第3版)》pdf下載在線閱讀,求百度網盤雲資源
《數據結構與演算法分析》(韋斯 (Mark Allen Weiss))電子書網盤下載免費在線閱讀
資源鏈接:
鏈接:
書名:數據結構與演算法分析
作者:韋斯 (Mark Allen Weiss)
出版社:機械工業出版社
出版年份:2013-2-1
頁數:614
內容簡介:
本書是國外數據結構與演算法分析方面的經典教材,使用卓越的Java編程語言作為實現工具討論了數據結構(組織大量數據的方法)和演算法分析(對演算法運行時間的估計)。
隨著計算機速度的不斷增加和功能的日益強大,人們對有效編程和演算法分析的要求也不斷增長。本書將演算法分析與最有效率的Java程序的開發有機地結合起來,深入分析每種演算法,並細致講解精心構造程序的方法,內容全面、縝密嚴格。
第3版的主要更新如下:
第4章包含AVL樹刪除演算法的實現。
第5章進行了全面修訂和擴充,現在包含兩種較新的演算法—cuckoo散列和hopscotch散列。
第7章包含基數排序的相關內容,並給出了下界證明。
第12章增加了後綴樹和後綴數組的相關材料,包括Karkkainen和Sanders的線性時間後綴數組構造演算法。
更新書中的代碼,使用了Java 7中的菱形運算符。
作者簡介:
Mark Allen Weiss佛羅里達國際大學計算與信息科學學院教授、副院長,本科教育主任和研究生教育主任。他於1987年獲得普林斯頓大學計算機科學博士學位,師從Bob Sedgewick。 他曾經擔任全美AP(Advanced Placement)考試計算機學科委員會的主席(2000—2004)。他的主要研究興趣是數據結構、演算法和教育學。
㈦ java十大演算法
演算法一:快速排序演算法
快速排序是由東尼·霍爾所發展的一種排序演算法。在平均狀況下,排序 n 個項目要Ο(n log n)次比較。在最壞狀況下則需要Ο(n2)次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他Ο(n log n) 演算法更快,因為它的內部循環(inner loop)可以在大部分的架構上很有效率地被實現出來。
快速排序使用分治法(Divide and conquer)策略來把一個串列(list)分為兩個子串列(sub-lists)。
演算法步驟:
1 從數列中挑出一個元素,稱為 "基準"(pivot),
2 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分區退出之後,該基準就處於數列的中間位置。這個稱為分區(partition)操作。
3 遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。
遞歸的最底部情形,是數列的大小是零或一,也就是永遠都已經被排序好了。雖然一直遞歸下去,但是這個演算法總會退出,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。
演算法二:堆排序演算法
堆排序(Heapsort)是指利用堆這種數據結構所設計的一種排序演算法。堆積是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。
堆排序的平均時間復雜度為Ο(nlogn) 。
演算法步驟:
創建一個堆H[0..n-1]
把堆首(最大值)和堆尾互換
3. 把堆的尺寸縮小1,並調用shift_down(0),目的是把新的數組頂端數據調整到相應位置
4. 重復步驟2,直到堆的尺寸為1
演算法三:歸並排序
歸並排序(Merge sort,台灣譯作:合並排序)是建立在歸並操作上的一種有效的排序演算法。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。
演算法步驟:
1. 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合並後的序列
2. 設定兩個指針,最初位置分別為兩個已經排序序列的起始位置
3. 比較兩個指針所指向的元素,選擇相對小的元素放入到合並空間,並移動指針到下一位置
4. 重復步驟3直到某一指針達到序列尾
5. 將另一序列剩下的所有元素
㈧ java怎麼讓數組的數字從大到小排序
將數字從大到小排序的方法:
例如簡一點的冒泡排序,將第一個數字和後面的數字逐個比較大小,如果小於,則互換位置,大於則不動。此時,第一個數為數組中的最大數。然後再將第二個數與後面的數逐個比較,以次類推。
示例代碼如下:
publicclassTest{
publicstaticvoidmain(String[]args){
int[]array={12,3,1254,235,435,236,25,34,23};
inttemp;
for(inti=0;i<array.length;i++){
for(intj=i+1;j<array.length;j++){
if(array[i]<array[j]){
temp=array[i];
array[i]=array[j];
array[j]=temp; //兩個數交換位置
}
}
}
for(inti=0;i<array.length;i++){
System.out.print(array[i]+"");
}
}
}
數組對於每一門編程語言來說都是重要的數據結構之一,當然不同語言對數組的實現及處理也不盡相同。
Java 語言中提供的數組是用來存儲固定大小的同類型元素。
你可以聲明一個數組變數,如 numbers[100] 來代替直接聲明 100 個獨立變數 number0,number1,....,number99
(8)數據結構與演算法java交換排序演算法擴展閱讀
Java中利用數組進行數字排序一般有4種方法:
1、選擇排序是先將數組中的第一個數作為最大或最小數,然後通過循環比較交換最大數或最小數與一輪比較中第一個數位置進行排序。
2、冒泡排序也是先將數組中的第一個數作為最大或最小數,循環比較相鄰兩個數的大小,滿足條件就互換位置,將最大數或最小數沉底。
3、快速排序法主要是運用Arrays類中的Arrays.sort方法()實現。
4、插入排序是選擇一個數組中的數據,通過不斷的插入比較最後進行排序。