① 數據結構有哪些基本演算法
數據結構是一門研究非數值計算的程序設計問題中的操作對象,以及它們之間的關系和操作等相關問題的學科。
可以理解為:程序設計 = 數據結構 + 演算法
數據結構演算法具有五個基本特徵:輸入、輸出、有窮性、確定性和可行性。
1、輸入:一個演算法具有零個或者多個輸出。以刻畫運算對象的初始情況,所謂0個輸入是指演算法本身定出了初始條件。後面一句話翻譯過來就是,如果一個演算法本身給出了初始條件,那麼可以沒有輸出。比如,列印一句話:NSLog(@"你最牛逼!");
2、輸出:演算法至少有一個輸出。也就是說,演算法一定要有輸出。輸出的形式可以是列印,也可以使返回一個值或者多個值等。也可以是顯示某些提示。
3、有窮性:演算法的執行步驟是有限的,演算法的執行時間也是有限的。
4、確定性:演算法的每個步驟都有確定的含義,不會出現二義性。
5、可行性:演算法是可用的,也就是能夠解決當前問題。
數據結果的基本演算法有:
1、圖搜索(廣度優先、深度優先)深度優先特別重要
2、排序
3、動態規劃
4、匹配演算法和網路流演算法
5、正則表達式和字元串匹配
6、三路劃分-快速排序
7、合並排序(更具擴展性,復雜度類似快速排序)
8、DF/BF 搜索 (要知道使用場景)
9、Prim / Kruskal (最小生成樹)
10、Dijkstra (最短路徑演算法)
11、選擇演算法
② 數據結構中有哪些基本演算法
數據結構中最基本的演算法有:查找、排序、快速排序,堆排序,歸並排序,,二分搜索演算法
等等。
1、用的最多也是最簡單的數據結構是線性表。
2、有前途的又難數據結構是圖 。
3、常用的80%演算法是排序和查找。
③ 數據結構 排序演算法
因為堆排序的性能不受時間的影響。
像這樣的還有:簡單選擇排序、歸並排序。
希望能幫到你~
④ 請問一下:有誰能總結數據結構中排序章內介紹各種演算法的時間復雜度呀,很急。。。
1.插入排序:每次將一個待排的記錄插入到前面的已經排好的隊列中的適當位置。
①.直接插入排序
直接排序法在最好情況下(待排序列已按關鍵碼有序),每趟排序只需作1次比較而不需要移動元素。所以n個元素比較次數為n-1,移動次數0。
最差的情況下(逆序),其中第i個元素必須和前面的元素進行比較i次,移動個數i+1,所以總共的比較次數 比較多,就不寫出來了
總結:是一種穩定的排序方法,時間復雜度O(n^2),排序過程中只要一個輔助空間,所以空間復雜度O(1)
②.希爾排序
縮小增量排序,對直接插入排序的一種改進
分組插入方法。
總結:是一種不穩定的排序方法,時間復雜度O(n^1.25),空間復雜度O(1)
2.交換排序
①.冒泡排序
最好的情況下,就是正序,所以只要比較一次就行了,復雜度O(n)
最壞的情況下,就是逆序,要比較n^2次才行,復雜度O(n^2)
總結:穩定的排序方法,時間復雜度O(n^2),空間復雜度O(1),當待排序列有序時,效果比較好。
②.快速排序
通過一趟排序將待排的記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一個部分的關鍵字小,然後再分別對這兩個部分記錄繼續進行排序,以達到整個序列有效。
總結:在所有同數量級O(nlogn)的排序方法中,快速排序是性能最好的一種方法,在待排序列無序時最好。演算法的時間復雜度是O(nlogn),最壞的時間復雜度O(n^2),空間復雜度O(nlogn)
3.選擇排序
①.直接選擇排序
和序列的初始狀態無關
總結:時間復雜度O(n^2),無論最好還是最壞
②.堆排序
直接選擇排序的改進
總結:時間復雜度O(nlogn),無論在最好還是最壞情況下都是O(nlogn)
4.歸並排序
總結:時間復雜度O(nlogn),空間復雜度O(n)
5.基數排序
按組成關鍵字的各個數位的值進行排序,是分配排序的一種。不需要進行排碼值間的比較就能夠進行排序。
總結:時間復雜度O(d(n+rd))
總總結:
n比較小的時候,適合 插入排序和選擇排序
基本有序的時候,適合 直接插入排序和冒泡排序
n很大但是關鍵字的位數較少時,適合 鏈式基數排序
n很大的時候,適合 快速排序 堆排序 歸並排序
無序的時候,適合 快速排序
穩定的排序:冒泡排序 插入排序 歸並排序 基數排序
復雜度是O(nlogn):快速排序 堆排序 歸並排序
輔助空間(大 次大):歸並排序 快速排序
好壞情況一樣:簡單選擇(n^2),堆排序(nlogn),歸並排序(nlogn)
最好是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)。
⑥ 數據結構中比較各種排序演算法 求詳解 ,,,,,,,,,,
排序演算法包括:插入排序、交換排序、選擇排序以及合並排序。
其中插入排序包括直接插入排序和Shell排序,交換排序包括冒泡排序和分化交換排序,選擇排序包括直接選擇排序和堆排序。
這些排序演算法中,直接插入排序、冒泡排序和直接選擇排序這三種排序的演算法平均時間復雜度是O(n的平方);分化交換排序、堆排序和合並排序這三種排序的演算法平均時間復雜度是
⑦ 用數據結構(先闡述演算法思想,然後寫出演算法) 寫出對n個關鍵字實施直接插入排序的演算法
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef int KeyType;
typedef int DataType;
typedef struct{
KeyType key;
//DataType data;
}SortItem,SqList[MAXSIZE];
int bubblesort(SqList L,int n);
int BiInsertSort(SqList L,int n);
int main()
{
int m,n,i,j,k;
SqList L;
scanf("%d",&n);
srand(0);
for(i=0;i<n;i++) L[i].key=rand()%1000;
k=BiInsertSort(L,n);
for(i=0;i<n;i++)
printf("\n\n%d",k);
system("pause");
return 0;
}
int bubblesort(SqList L,int n)
{
int i,j,over,count=0;
SortItem p;
for(i=0;i<n-1;i++)
{
over=1;
count++;
for(j=n-1;j>i;j--)
{
if( count++&&L[j].key<L[j-1].key)
{
p=L[j];
L[j]=L[j-1];
L[j-1]=p;
over=0;
count++;
}
}
if(over) break;
}
return count+1;
}
int BiInsertSort(SqList L,int n)
{
int i,j,low,upper,mid;
SortItem p;
for(i=1;i<n;i++)
{
p=L[i];
low=0;
upper=i-1;
while(low<=upper)
{
mid=(low+upper)/2;
if(p.key<L[mid].key) upper=mid-1;
else low=mid+1;
}
for(j=i-1;j>=low;j--) L[j+1]=L[j];
L[low]=p;
}
return 0;
}
⑧ 數據結構的排序演算法中,哪些排序是穩定的,哪些排序是不穩定的
一、穩定排序演算法
1、冒泡排序
2、雞尾酒排序
3、插入排序
4、桶排序
5、計數排序
6、合並排序
7、基數排序
8、二叉排序樹排序
二、不穩定排序演算法
1、選擇排序
2、希爾排序
3、組合排序
4、堆排序
5、平滑排序
6、快速排序
排序(Sorting) 是計算機程序設計中的一種重要操作,它的功能是將一個數據元素(或記錄)的任意序列,重新排列成一個關鍵字有序的序列。
一個排序演算法是穩定的,就是當有兩個相等記錄的關鍵字R和S,且在原本的列表中R出現在S之前,在排序過的列表中R也將會是在S之前。
不穩定排序演算法可能會在相等的鍵值中改變紀錄的相對次序,但是穩定排序演算法從來不會如此。不穩定排序演算法可以被特別地實現為穩定。
做這件事情的一個方式是人工擴充鍵值的比較,如此在其他方面相同鍵值的兩個對象間之比較,就會被決定使用在原先數據次序中的條目,當作一個同分決賽。然而,要記住這種次序通常牽涉到額外的空間負擔。
(8)數據結構插入排序演算法擴展閱讀:
排序演算法的分類:
1、通過時間復雜度分類
計算的復雜度(最差、平均、和最好性能),依據列表(list)的大小(n)。
一般而言,好的性能是 O(nlogn),且壞的性能是 O(n^2)。對於一個排序理想的性能是 O(n)。
而僅使用一個抽象關鍵比較運算的排序演算法總平均上總是至少需要 O(nlogn)。
2、通過空間復雜度分類
存儲器使用量(空間復雜度)(以及其他電腦資源的使用)
3、通過穩定性分類
穩定的排序演算法會依照相等的關鍵(換言之就是值)維持紀錄的相對次序。
⑨ 數據結構中哪種排序方式效率最好
簡單排序的演算法(直接插入,冒泡,簡單選擇排序)簡單且穩定,適合與待排記錄較小的情況,當當待排序的關鍵碼序列已經基本有序時,用直接插入排序最快。
就平均時間的性能而言,快速排序最佳,即排序速度最快,所以在隨機情況下,快速排序是最佳選擇。一般情況下,快速排序效率最好。
既要節省空間,又要有較快的排序速度,堆排序是最佳選擇,其不足之處是建堆時需要消耗較多時間。
若希望排序是穩定的,且有較快的排序速度,則可選用2路歸並排序,其缺點需要較大的輔助空間分配。