快速排序和歸併排序 使用圖形化介面的方式
2.8.1題目描述
使用圖形化介面的方式,顯示快速排序和歸併排序的效果。
2.8.2程式使用說明
Java version: 1.8.0_111
IDE:eclipse
歸併排序演示,Eclipse開啟MergeSortDemonstration.java檔案,右鍵run,出現圖形化介面,演示自動進行。
快速排序演示,同上,執行QuickSortDemonstration.java檔案
2.8.3簡要分析和設計
歸併排序分析:
實現歸併排序的另一種方式是從小陣列開始歸併:首先我們將陣列的每一個元素都當做一個只有一個元素的陣列,然後將其兩兩歸併。然後我們將整個陣列的每兩個元素都當做一個小陣列,然後將其兩兩歸併,然後四個四個歸併,依次類推,直到最後歸併成一個大陣列,排序就完成了。如下是歸併排序的演示圖:
(圖片來源於http://www.cnblogs.com/jingmoxukong/p/4308823.html)
歸併排序虛擬碼:
MERGE SORT(A, p, r) //對A[p..r]進行歸併排序
if p < r
then q ← (p+r)/2 //將A[p..r]分成兩個子序列進行遞迴歸併排序
MERGE-SORT (A, p, q)
MERGE-SORT (A, q+1, r)
MERGE (A, p, q, r)
MERGE(A, p, q, r)
n1 ← q-p+1; //計算左半部分已排序序列的長度
n2 2 ← r-q; //計算右半部分已排序序列的長度
create arrays L[1..n1+1] and R[1..n2+1]
for i ← 1 to n1
do L[i] ← A[p + i-1] //copy左半部分已排序序列到L中
for j ← 1 to n2
do R[j] ← A[q + j] //copy右半部分已排序序列
L[n1+1] ←∞
R[n2+1] ← ∞
i ← 1
j ← 1
for k ← p to r //進行合併
do if L[i] < R[j]
then A[k] ← L[i]
i ← i + 1
else A[k] ← R[j]
j ← j + 1
歸併排序複雜度:O(n log n)
快速排序分析:
設要排序的陣列是A[0]……A[N-1],首先任意選取一個數據(通常選用陣列的第一個數)作為關鍵資料,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。
一趟快速排序的演算法是:
1)設定兩個變數i、j,排序開始的時候:i=0,j=N-1;
2)以第一個陣列元素作為關鍵資料,賦值給key,即key=A[0];
3)從j開始向前搜尋,即由後開始向前搜尋(j--),找到第一個小於key的值A[j],將A[j]和A[i]互換;
4)從i開始向後搜尋,即由前開始向後搜尋(i++),找到第一個大於key的A[i],將A[i]和A[j]互換;
5)重複第3、4步,直到i=j; (3,4步中,沒找到符合條件的值,即3中A[j]不小於key,4中A[i]不大於key的時候改變j、i的值,使得j=j-1,i=i+1,直至找到為止。找到符合條件的值,進行交換的時候i, j指標位置不變。
快速排序虛擬碼:
quicksort(A, lo, hi)
if lo < hi
p = partition(A, lo, hi)
quicksort(A, lo, p - 1)
quicksort(A, p + 1, hi)
partition(A, lo, hi)
pivot = A[hi]
i = lo
for j = lo to hi - 1
if A[j] <= pivot
swap A[i] with A[j]
i = i + 1
swap A[i] with A[hi]
return i
快速排序時間複雜度:O(nlogn)
2.8.4測試用例
歸併排序測試用例:
{6,3,19,40,45,30,33,35,34,23,18,27,39,14,17,31,36}
執行結果:
快速排序執行結果:
2.8.5原始碼
結構圖:
package four.four;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 歸併排序的演示系統
* @author ym
*
*/
public class MergeSortDemonstration extends JPanel{
/**
* 序列號
*/
private static final long serialVersionUID = 1L;
//陣列,儲存動畫演示數字
private int[] paints=null;
public MergeSortDemonstration(int[] paints){
this.paints= paints;
}
/**
* 歸併排序
*
* start用來記錄在
* 最開始陣列起始位置
*
* @param array
* @return
*/
public void mergeSort(int[] array,int start){
if(array.length>1){
int len = array.length;
int[] array1 = new int[len/2];
int[] array2 = new int[len-len/2];
System.arraycopy(array,0,array1,0,len/2);
System.arraycopy(array, len/2,array2,0,len-len/2);
//遞迴
mergeSort(array1,start);
mergeSort(array2,start+len/2);
//合併
int index1 = 0;
int index2 = 0;
while(index1<array1.length&&index2<array2.length){
if(array1[index1]<array2[index2]){
array[index1+index2]=array1[index1++];
}
else{
array[index1+index2]=array2[index2++];
}
}
while(index1<array1.length){
array[index1+index2]=array1[index1++];
}
while(index2<array2.length){
array[index1+index2]=array2[index2++];
}
System.arraycopy(array,0,paints,start,array.length);
repaint();
//讓動畫動作變慢
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
protected void paintComponent(Graphics g) {
if(getPaints()==null){
return;
}
super.paintComponent(g);
g.setColor(Color.blue);
int width = getWidth();
int height = getHeight();
//畫縱軸
g.drawLine(20,10,20,height-20);
//畫橫軸
g.drawLine(10,height-20,width-20,height-20);
//每個數字多佔寬度
int digitWidth = (width-40)/paints.length;
//獲取最大的數字
int maxNum = 0;
for(int i=0;i<paints.length;i++){
if(paints[i]>maxNum){
maxNum=paints[i];
}
}
//根據陣列畫柱狀圖
for(int i=0;i<paints.length;i++){
//計算數字位置
int digitX = 20+i*digitWidth+digitWidth/2;
int digitY = height-5;
//畫數字
g.drawString(""+paints[i], digitX, digitY);
//條狀圖高度
int barHeight =(height-30)/maxNum*paints[i];
//畫數字大小對應的條狀圖
g.drawRect(digitX,height-20-barHeight,15,barHeight);
}
}
public int[] getPaints() {
return paints;
}
public void setPaints(int[] paints) {
this.paints = paints;
}
public static void main(String[] args) {
int[] array = {6,3,19,40,45,30,33,35,34,23,18,27,39,14,17,31,36};
MergeSortDemonstration MSD = new MergeSortDemonstration(array);
JFrame JF = new JFrame("歸併排序");
JF.setSize(600,600);
JF.setLocationRelativeTo(null);
JF.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JF.add(MSD);
JF.setVisible(true);
//排序
MSD.mergeSort(array,0);
}
}
package four.four;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 排序演示
* @author ym
*
*/
public class QuickSortDemonstration extends JPanel{
/**
* 序列號
*/
private static final long serialVersionUID = 1L;
public QuickSortDemonstration(int[] array){
this.paints= array;
}
//劃分值下標
private int index=0;
/**
* 儲存需要畫的陣列
*/
private int[] paints = null;
public int[] getPaints() {
return paints;
}
public void setPaints(int[] paints) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.paints = paints;
repaint();
}
/**
* 交換兩個元素的順序
*
* @param array
* @param i
* @param j
*/
public void swap(int[] array,int i,int j,int position){
int temp = array[i];
array[i]=array[j];
array[j]=temp;
//設定劃分元素的下標值
setIndex(position);
//更新待畫陣列
setPaints(array);
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
/**
* 快速排序
*
* @param arr
* @param i
* @param j
*/
public void quickSort(int[] array,int i,int j){
if(i<j){
int index = divide(array,i,j);
quickSort(array,i,index-1);
quickSort(array, index+1, j);
}
}
/**
* 左右掃描分割
*
* @param arr
* @param i
* @param j
* @return
*/
public int divide(int[] array,int i,int j){
int index=i;
int patition=array[i];
int low= i+1;
int high=j;
while(low<high){
while(low<high&&array[low]<patition){
low++;
}
while(low<high&&array[high]>patition){
high--;
}
if(low<high){
swap(array,low,high,index);
}
}
while(array[high]>array[index]){
high--;
}
if(high>index){
swap(array,high,index,index);
}
return high;
}
@Override
protected void paintComponent(Graphics g) {
if(getPaints()==null){
return;
}
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
//畫縱軸
g.drawLine(20,10,20,height-20);
//畫橫軸
g.drawLine(10,height-20,width-20,height-20);
//每個數字多佔寬度
int digitWidth = (width-40)/paints.length;
//獲取最大的數字
int maxNum = 0;
for(int i=0;i<paints.length;i++){
if(paints[i]>maxNum){
maxNum=paints[i];
}
}
//根據陣列畫柱狀圖
for(int i=0;i<paints.length;i++){
//計算數字位置
int digitX = 20+i*digitWidth+digitWidth/2;
int digitY = height-5;
//畫數字
g.drawString(""+paints[i], digitX, digitY);
//條狀圖高度
int barHeight =(height-30)/maxNum*paints[i];
//設定劃分值對應條狀圖的顏色為紅色,其餘為黑色
if(this.index==i){
g.setColor(Color.red);
}
else{
g.setColor(Color.blue);
}
//畫數字大小對應的條狀圖
g.drawRect(digitX,height-20-barHeight,15,barHeight);
}
}
public void print(int[] array){
for(int i=0;i<array.length;i++){
System.out.print(" "+array[i]);
}
System.out.println();
}
public static void main(String[] args) {
int[] array = {6,3,19,40,45,30,33,35,34,23,18,27,39,14,17,31,36};
QuickSortDemonstration SD = new QuickSortDemonstration(array);
JFrame JF = new JFrame("QuickSort");
JF.setSize(600,600);
JF.setLocationRelativeTo(null);
JF.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JF.add(SD);
JF.setVisible(true);
//排序
SD.quickSort(array, 0, array.length-1);
}
}
相關推薦
快速排序和歸併排序 使用圖形化介面的方式
2.8.1題目描述 使用圖形化介面的方式,顯示快速排序和歸併排序的效果。 2.8.2程式使用說明 Java version: 1.8.0_111 IDE:eclipse 歸併排序演示,Eclipse開啟MergeSortDemonstration.java檔案,右鍵run,
快速排序和歸併排序的非遞迴實現
1.快速排序 # 快速排序 def partition(li, left, right): i = left j = right r = random.randint(i, j) li[i], li[r] = li[r], li[i] tmp = li[i]
Java快速排序和歸併排序區別和實現
快速排序與歸併排序的概念: 快速排序(Quicksort)是對氣泡排序的一種改進。 快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩
快速排序和歸併排序
分而治之(divide - conquer);每個遞迴過程涉及三個步驟 第一, 分解: 把待排序的 n 個元素的序列分解成兩個子序列, 每個子序列包括 n/2 個元素. 第二, 治理: 對每個子序列
快速排序和歸併排序演算法
快速排序是最快的排序方式,但是它不穩定,它的時間複雜度為O(nlog(n)),空間複雜度為O(logn),它的原理大概的分為如下: 設要排序的陣列是A[0]……A[N-1],首先任意選取一個數據(通常選用陣列的第一個數)作為關鍵資料,然後將所有比它小的數都放到
排序演算法之快速排序和歸併排序
申明:此博文轉自他人,感覺不錯特轉載供大家分享 摘要:一般評判排序演算法的標準有時間代價,空間代價和穩定性。本文主要討論性質相對比較好且作者喜歡的快速排序演算法和歸併排序演算法,並對此這做了一定比較。 正文: 常見的排序演算法大致分為四類: 1.插入排序
理解快速排序和歸併排序
從本人很久以前的部落格上轉過來的。原創哈! 1,快速排序 快速排序通過分割值列,然後遞迴的對兩個部分進行排序,從而實現對值列的排序。它的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部
快速排序和歸併排序的時間複雜度分析——通俗易懂
# 一、前言 今天面試的時候,被問到歸併排序的時間複雜度,這個大家都知道是``O(nlogn)``,但是面試官又繼續問,怎麼推匯出來的。這我就有點懵了,因為之前確實沒有去真正理解這個時間複雜度是如何得出的,於是就隨便答了一波(理解了之後,發現面試的時候答錯了......)。 &em
第一篇部落格:對插入排序和歸併排序演算法時間複雜度的學習
第一次寫部落格,心情難免有點忐忑,不過為了達到心中的小目標,儘可能的用有效率的方法去提升自己。廢話不多說,下面進入正題。 剛看了網易公開課裡的《麻省理工學院公開課:演算法導論》,受益頗深!國外學校的講課方式確實更有趣味和深度(或許因為在學校壓根沒聽進去過幾節課)
希爾排序和歸併排序
1.首先說一下為什麼要搞這些東西。當然是資料結構考試啦,再來複習一下資料結構以及一些常用的演算法,平時都是用的 是sort真的自己敲了一下發現還是不容易一次敲對的。 2.首先是希爾排序,ShellSort,沒錯這個排序方法就是希爾發明的,作為第一個打破排序時間複雜度O(n^2)的方法。首先我
第三週作業——氣泡排序和歸併排序(執行氣泡排序)
我冒個泡,然後開始排序! 讀入檔案和排序後寫出檔案的氣泡排序。異常處理全都是throws 氣泡排序: package exercise3; import java.io.BufferedReader; import java.io.BufferedWriter; imp
排序演算法總結-選擇排序、插入排序、歸併排序和快速排序
前言: 感覺好久沒寫部落格了,十月份的計劃是:要開始深入攻克資料結構和演算法,耽誤好久了,這都月末了,抓緊時間又學習了一波,趕緊來分享了一下,使用的語言是C++,最開始學資料結構一定要用C,掌握紮實之後,想學演算法,用C++比較好,C封裝沒有那麼好,寫起來沒有那麼容易了。 一、準備工作
Java實現快速排序、歸併排序、堆排序和希爾排序
快速排序 演算法思想 1.將陣列的第一個元素取為target,定義兩個指標i 和 j; 2.指標i ,從左向右找到第一個比target大的元素,指標j從右向左找到第一個比target小的元素,
插入排序,歸併排序,快速排序的實現和速度比較(包含二分法查詢所有匹配元素)
最近在學習排序演算法,實現後比較了花費時間情況,現在總結一下插入排序的時間複雜度是O(n²),是一種很直觀的排序方式。歸併排序為O(nlogn),實現起來也比較簡單。快速排序平均時間複雜度也是O(nlogn),實現起來比歸併複雜一些。經過比較發現快速排序比歸併排序要快一些,大
Python排序算法動態圖形化演示(實現代碼)
ret start quick 方法 jpg 位置 如果 code nbsp 1、冒泡排序 冒泡排序是最簡單也是最容易理解的排序方法,其原理就是重復地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重復地進行直到沒有再需要交換
python實現堆排序、快速排序、歸併排序
堆排序 快速排序 快速排序一般選擇序列的兩頭位置,分別記為low和high,第一遍排序將low指標對應的值作為一個key值,試圖將大於key值的放在它的右邊,小於key值的放在左邊。具體實現是以key為標準,將high指標依
排序演算法(直接插入、氣泡排序、選擇排序、快速排序、希爾排序、堆排序、歸併排序)
main函式 int main() { int data[] = {1,2,6,3,4,7,7,9,8,5}; //bubble_sort(data,10); //select_sort(data,10); Insert_Sort(data,10); fo
python 快速排序和插入排序比較
#coding=utf-8 #插入排序 import time testArr = [5,3,2,7,8,0,22,32,-1]; arrLen = testArr.__len__(); def insertSort(arr): for num in range(1,arrLen):
vue-cli3.0 使用圖形化介面建立和管理專案
1.開啟終端輸入vue ui vue ui 2.建立專案 3.選擇一套預設,點選建立專案按鈕 4.等待安裝 5.安裝完成後 6.可以新增外掛 7.專案依賴管理 8.專案配置管理 9.
資料結構--氣泡排序、歸併排序、快速排序、選擇排序、插入排序(Java版)
一、氣泡排序 1、思路 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。 針對所有的元素重複以上的步驟,直到沒有任何一對元素需要比較。 2、實現 /** * 排序演算法的介面 * @author hoaven */ pu