㈠ 把快速排序遞歸演算法改成非遞歸
可以用棧把那些要排的東西記下來如,起始位置,結束位置,基準位置,再一個一個的排,直到棧為空
//還有很多沒有寫你自己去填上
struct qq{
int frist;
int last;
}QQ[MAXSIZE];
int a[max];
struct qq dd,ff;
while(!empty(QQ)){
dd=pop(QQ);//不為空就出棧
qkOne(a[],dd->frist,dd->last);//把這一部分排好;
if(dd->frist<i){ ff->frist=dd-frist;ff->last=i-1;push(ff,QQ);}//這里改為入棧就可以了,下同
if(i<dd->last){ff->frist=i+1;ff->last=dd->last;push(ff,QQ);}
}
}
void qkOne(int a[],int frist,int last);//frist為起始位置,last為終止位置
{ int x,i,j;
i=frist;
j=last;
x=a[i];//將第一個值保存在x中,做基準值。
while(i!=j)
{
while(i<j && a[j]>=x)
; /*自右向左掃描*/
if(i<j)
{
;
i++;
}
while(i<j&&a[i]<=x)
i++; /*自左向右掃描*/
if(i<j)
{ a[j]=a[i];
;
}
}
;
㈡ java中有哪幾種常用的排序方法
最主要的是冒泡排序、選擇排序、插入排序以及快速排序
1、冒泡排序
冒泡排序是一個比較簡單的排序方法。在待排序的數列基本有序的情況下排序速度較快。若要排序的數有n個,則需要n-1輪排序,第j輪排序中,從第一個數開始,相鄰兩數比較,若不符合所要求的順序,則交換兩者的位置;直到第n+1-j個數為止,第一個數與第二個數比較,第二個數與第三個數比較,......,第n-j個與第n+1-j個比較,共比較n-1次。此時第n+1-j個位置上的數已經按要求排好,所以不參加以後的比較和交換操作。
例如:第一輪排序:第一個數與第二個數進行比較,若不符合要求的順序,則交換兩者的位置,否則繼續進行二個數與第三個數比較......。直到完成第n-1個數與第n個數的比較。此時第n個位置上的數已經按要求排好,它不參與以後的比較和交換操作;第二輪排序:第一個基輪州數與第二個數進行比較,......直到完成第n-2個數與第n-1個數的比較;......第n-1輪排序:第一個數與第二個數進行比較,若符合所要求的順序,則結束冒泡法排序;若不符合要求的順序,則交換兩者的位置,然後結束冒泡法排序。
共n-1輪排序處理,第j輪進行n-j次比較和至多n-j次交換。
從以上排序過程可以桐汪看出,較大的數像氣泡一樣向上冒,而較小的數往下沉,故稱冒泡法。
public void bubbleSort(int a[])
{
int n = a.length;
for(int i=0;i<n-1;i++)
{
for(int j=0;j<n-i-1;j++)
{
if(a[j] > a[j+1])
{
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
2、選擇排序
選擇法的原理是先將第一個數與後面的每一個數依次比較,不斷將將小的賦給第一個數,從而找出最小的,然後第二個數與後面的每一個數依次比較,從而找出第二小的,然後第三個數與後面的每一個數依次比較,從而找出第三小的.....直到找到最後一個數。
public void sort(int x[])
{
int n=x.length;
int k,t;
for(int i=0;i<n-1;i++)
{
k=i;
for(int j=i+1;j=n;j++)
{
if(x[j]>x[k])k=j;
if(k!=i)
{
t=x[i];
x[i]=x[k];
x[k]=t;
}
}
}
}
3、插入排序
插入排序的原理是對數組中的第i個元素,認為它前面的i-1個已經排序好,然後將它插入到前面的i-1個元素中。插入排序對少量元素的排序較為有效.
public void sort(int obj[])
{
for(int j=1;j<obj.length;j++)
{
int key=obj[j];
int i=j-1;
while(i>=0&&obj[i]>key)
{
obj[i+1]=obj[i];
i--;
}
obj[i+1]=key;
}
}
4、快速排序
快速排序是對冒泡排序搏蔽的一種改進。它的基本思想是:通過一次排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按次方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此大道整個數據變成有序序列。
public void quickSort(int obj[],int low,int high)
{
int i=low;
int j=high;
int keyValue=obj[i];
while(i<j)
{
int temp=0;
while(i<j&&obj[j]>=keyValue)
{
j=j-1;
}
temp=obj[j];
obj[j]=obj[i];
obj[i]=temp;
while(i<j&&obj[i]<=keyValue)
{
i=i+1;
}
temp=obj[j];
obj[j]=ojb[i];
obj[i]=temp;
}
obj[i]=keyValue;
if(low<i-1)
{
quickSort(obj,low,i-1);
}
if(high>i+1)
{
quickSort(obj,i+1,high);
}
}
㈢ java排序演算法中,快速排序慢好多,還容易爆棧,求指教
代碼沒問題
我今天也遇到一樣的問題
猜測是因為快排遞歸創建了很多棧,當數據量過大時就棧溢出
我的解決方法是自己也寫了一個快速排序非遞歸的方法
但是實際耗費的時間仍然不如其他演算法
㈣ 快速排序的非遞歸實現
快速排序簡單的說就是選擇一個基準,將比起大的數放在一邊,小的數放到另一邊。對這個數的兩邊再遞歸上述方法。
如改爛本題
66 13 51 76 81 26 57 69 23,以66為基準,升序排序的話,比66小的放左邊,比66大的放右邊, 類似這種情況 13 。。。 66。。。69
具體快速排序的規則一般如下:
從右邊開始查找比66小的數,找到的時候先等一下,再從左邊開始找比66大的數,將這兩個數藉助66互換一下位置,繼續這個核高漏過程直到兩次查找過程碰頭。
例子中:
66 13 51 76 81 26 57 69 23
從右邊找到23比66小,互換
23 13 51 76 81 26 57 69 66
從左邊找到76比66大,互換
23 13 51 66 81 26 57 69 76
繼續從右邊找到57比66小,互換
23 13 51 57 81 26 66 69 76
從左邊查找,81比66大,互換
23 13 51 57 66 26 81 69 76
從右邊開始查找26比66小,互換
23 13 51 57 26 66 81 69 76
從左邊開始查找,發現已經跟右邊查找碰頭了,結念敗束,第一堂排序結束
下面排序C語言的排序快速代碼,參考一下
void sort(int *a, int left, int right)
{
if(left >= right)/*如果左邊索引大於或者等於右邊的索引就代表已經整理完成一個組了*/
{
return ;
}
int i = left;
int j = right;
int key = a[left];
while(i < j) /*控制在當組內尋找一遍*/
{
while(i < j && key <= a[j])
/*而尋找結束的條件就是,1,找到一個小於或者大於key的數(大於或小於取決於你想升
序還是降序)2,沒有符合條件1的,並且i與j的大小沒有反轉*/
{
j--;/*向前尋找*/
}
a[i] = a[j];
/*找到一個這樣的數後就把它賦給前面的被拿走的i的值(如果第一次循環且key是
a[left],那麼就是給key)*/
while(i < j && key >= a[i])
/*這是i在當組內向前尋找,同上,不過注意與key的大小關系停止循環和上面相反,
因為排序思想是把數往兩邊扔,所以左右兩邊的數大小與key的關系相反*/
{
i++;
}
a[j] = a[i];
}
a[i] = key;/*當在當組內找完一遍以後就把中間數key回歸*/
sort(a, left, i - 1);/*最後用同樣的方式對分出來的左邊的小組進行同上的做法*/
sort(a, i + 1, right);/*用同樣的方式對分出來的右邊的小組進行同上的做法*/
/*當然最後可能會出現很多分左右,直到每一組的i = j 為止*/
}
㈤ 編寫 快速排序的非遞歸演算法
終於編寫出來了,我寫了兩種,你看看:下面是代碼:
/*非遞歸演算法1
遞歸演算法的開銷很大,所以在下編了一個非遞歸的,演算法描述如下:
A non-recursive version of quick sort using stack:
There are 2 stacks, namely one which stores the start of
a subarray and the other which stores the end of the
subarray.
STEP 1: while the subarray contains more than one element
,i.e. from Do {
SUBSTEP 1. pivot=Partion(subarray);
SUBSTEP 2. keep track of the right half of the current
subarray i.e. push (pivot+1) into stackFrom, push (to) into stackTo
SUBSTEP 3. go on to deal with the left half of
the current subarray i.e. to=pivot-1
}
STEP 2: if(neither of the stacks is empty)
Get a new subarray to deal with from the stacks.
i.e. start=pop(stackFrom); to=pop(stackTo);
STEP 3: both stacks are empty, and array has
been sorted. The program ends.
*/*/
void UnrecQuicksort(int q[],int low,int high)
{stack s1;<br/>stacks2;<br/> s1.push(low);<br/> s2.push(high);<br/> int tl,th,p;<br/> while(!s1.empty() && !s2.empty())<br/> {tl=s1.top();th=s2.top();<br/> s1.pop();s2.pop();<br/> if(tl>=th) continue;<br/> p=partition(q,tl,th);<br/> s1.push(tl);s1.push(p+1);<br/> s2.push(p-1);s2.push(th);<br/> }
}
/*非遞歸演算法2
要把遞歸演算法改寫成非遞歸演算法,可引進一個棧,這個棧的大小取決於遞歸調用的深度,最
多不會超過n,如果每次都選較大的部分進棧,處理較短的部分,遞歸深度最多不超過log2n
,也就是說快速排序需要的附加存儲開銷為O(log2n)。
*/
void UnrecQuicksort2(int q[],int low,int high)
{int *a;<br/> int top=0,i,j,p;<br/> a=new int[high-low+1];<br/> if(a==NULL) return;<br/> a[top++]=low;<br/> a[top++]=high;<br/> while(top>0)<br/> {i=a[--top];<br/> j=a[--top];<br/> while(j {p=partition(q,j,i);<br/> if(p-j {//先分割前部,後部進棧<br/>a[top++]=p+1;<br/> a[top++]=i;<br/> i=p-1;<br/> }
else
{//先分割後部,前部進棧
a[top++]=j;
a[top++]=p-1;
j=p+1;
}
}
}
}
/*列印輸出*/
void display(int p[],int len)
{for(int i=0;i cout<}
/*測試*/
int _tmain(int argc, _TCHAR* argv[])
{int a[]={49,65,97,12,23,41,56,14};
quicksort(a,0,7);
//UnrecQuicksort(a,0,7);
//UnrecQuicksort2(a,0,7);
display(a,8);
return 0;
}
㈥ 如何用java輸出一個數組的全排列不能用遞歸,用遞歸的話,很快就內存溢出了!
我覺得吧,你輸出一告凳個全排列用不了多少內存,怎麼就能溢出呢?
首先,遞歸費不了多少內碰槐存,應該可以完成任務。
其次,你遞歸都幹了些什麼?別告訴我每層遞歸把數組復制一遍,你把位置遞歸一下就可以了。
如果不喜歡遞歸,可以自己弄個棧,其實襪吵旅差不多,速度略快,空間略小。
如果還是不明白,把全部源碼貼出來看看。
㈦ 請大神幫我看一下 這個非遞歸快速排序 為什麼在排待排數組含相同元素的時候會出錯
左右比較的時候都沒有把相當的情況考慮進去,當出現相等的時候,你的代碼就會陷入死循環
㈧ 請問一下java快速排序源代碼
快速排序:
package org.rut.util.algorithm.support;
import org.rut.util.algorithm.SortUtil;
/**
* @author treeroot
* @since 2006-2-2
* @version 1.0
*/
public class QuickSort implements SortUtil.Sort{
/* (non-Javadoc)
* @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
*/
public void sort(int[] data) {
quickSort(data,0,data.length-1);
}
private void quickSort(int[] data,int i,int j){
int pivotIndex=(i+j)/歲橡2;
//swap
SortUtil.swap(data,pivotIndex,j);
int k=partition(data,i-1,j,data[j]);
SortUtil.swap(data,k,j);
if((k-i)>1) quickSort(data,i,k-1);
if((j-k)>悄雀慶1) quickSort(data,k+1,j);
}
/**
* @param data
* @param i
* @param j
* @return
*/
private int partition(int[] data, int l, int r,int pivot) {
do{
while(data[++l]<pivot);
while((r!=0)&&data[--r]>pivot);
SortUtil.swap(data,l,r);
}
while(l<r);
SortUtil.swap(data,l,r);
return l;
}
}
改進後的快速排序:
package org.rut.util.algorithm.support;
import org.rut.util.algorithm.SortUtil;
/**
* @author treeroot
* @since 2006-2-2
* @version 1.0
*/
public class ImprovedQuickSort implements SortUtil.Sort {
private static int MAX_STACK_SIZE=4096;
private static int THRESHOLD=10;
/啟握* (non-Javadoc)
* @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
*/
public void sort(int[] data) {
int[] stack=new int[MAX_STACK_SIZE];
int top=-1;
int pivot;
int pivotIndex,l,r;
stack[++top]=0;
stack[++top]=data.length-1;
while(top>0){
int j=stack[top--];
int i=stack[top--];
pivotIndex=(i+j)/2;
pivot=data[pivotIndex];
SortUtil.swap(data,pivotIndex,j);
//partition
l=i-1;
r=j;
do{
while(data[++l]<pivot);
while((r!=0)&&(data[--r]>pivot));
SortUtil.swap(data,l,r);
}
while(l<r);
SortUtil.swap(data,l,r);
SortUtil.swap(data,l,j);
if((l-i)>THRESHOLD){
stack[++top]=i;
stack[++top]=l-1;
}
if((j-l)>THRESHOLD){
stack[++top]=l+1;
stack[++top]=j;
}
}
//new InsertSort().sort(data);
insertSort(data);
}
/**
* @param data
*/
private void insertSort(int[] data) {
int temp;
for(int i=1;i<data.length;i++){
for(int j=i;(j>0)&&(data[j]<data[j-1]);j--){
SortUtil.swap(data,j,j-1);
}
}
}
}
㈨ java快速排序簡單代碼
.example-btn{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.example-btn:hover{color:#fff;background-color:#47a447;border-color:#398439}.example-btn:active{background-image:none}div.example{width:98%;color:#000;background-color:#f6f4f0;background-color:#d0e69c;background-color:#dcecb5;background-color:#e5eecc;margin:0 0 5px 0;padding:5px;border:1px solid #d4d4d4;background-image:-webkit-linear-gradient(#fff,#e5eecc 100px);background-image:linear-gradient(#fff,#e5eecc 100px)}div.example_code{line-height:1.4em;width:98%;background-color:#fff;padding:5px;border:1px solid #d4d4d4;font-size:110%;font-family:Menlo,Monaco,Consolas,"Andale Mono","lucida console","Courier New",monospace;word-break:break-all;word-wrap:break-word}div.example_result{background-color:#fff;padding:4px;border:1px solid #d4d4d4;width:98%}div.code{width:98%;border:1px solid #d4d4d4;background-color:#f6f4f0;color:#444;padding:5px;margin:0}div.code div{font-size:110%}div.code div,div.code p,div.example_code p{font-family:"courier new"}pre{margin:15px auto;font:12px/20px Menlo,Monaco,Consolas,"Andale Mono","lucida console","Courier New",monospace;white-space:pre-wrap;word-break:break-all;word-wrap:break-word;border:1px solid #ddd;border-left-width:4px;padding:10px 15px} 排序演算法是《數據結構與演算法》中最基本的演算法之一。排序演算法可以分為內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。常見的內部排序演算法有:插入排序、希爾排序、選擇排序、冒泡排序、歸並排序、快速排序、堆排序、基數排序等。以下是快速排序演算法:
快速排序是由東尼·霍爾所發展的一種排序演算法。在平均狀況下,排序 n 個項目要 Ο(nlogn) 次比較。在最壞譽渣宏狀況下則需要 Ο(n2) 次比較,但這種狀況並不常見。事實上,快速排序梁灶通常明顯比其他 Ο(nlogn) 演算法更快,因為它的內部循環(inner loop)可以在大部分的架構上很有效率地被實現出來。
快速排序使用分治法(Divide and conquer)策略來把一個串列(list)分為兩個子串列(sub-lists)。
快速排序又是一種分而治之思想在排序演算法上的典型應用。本質上來看,快速排序應該算是在冒慶冊泡排序基礎上的遞歸分治法。
快速排序的名字起的是簡單粗暴,因為一聽到這個名字你就知道它存在的意義,就是快,而且效率高!它是處理大數據最快的排序演算法之一了。雖然 Worst Case 的時間復雜度達到了 O(n?),但是人家就是優秀,在大多數情況下都比平均時間復雜度為 O(n logn) 的排序演算法表現要更好,可是這是為什麼呢,我也不知道。好在我的強迫症又犯了,查了 N 多資料終於在《演算法藝術與信息學競賽》上找到了滿意的答案:
快速排序的最壞運行情況是 O(n?),比如說順序數列的快排。但它的平攤期望時間是 O(nlogn),且 O(nlogn) 記號中隱含的常數因子很小,比復雜度穩定等於 O(nlogn) 的歸並排序要小很多。所以,對絕大多數順序性較弱的隨機數列而言,快速排序總是優於歸並排序。
1. 演算法步驟
從數列中挑出一個元素,稱為 "基準"(pivot);
重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分區退出之後,該基準就處於數列的中間位置。這個稱為分區(partition)操作;
遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序;
2. 動圖演示
代碼實現 JavaScript 實例 function quickSort ( arr , left , right ) {
var len = arr. length ,
partitionIndex ,
left = typeof left != 'number' ? 0 : left ,
right = typeof right != 'number' ? len - 1 : right ;
if ( left