データ構造と アルゴリズム第13回 -...

18
データ構造と アルゴリズム第13知能情報学メジャー 和⽥俊和

Upload: others

Post on 09-Jul-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

データ構造とアルゴリズム第13回

知能情報学メジャー和⽥俊和

Page 2: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

5整列5.1整列とは5.2単純な整列アルゴリズム5.3挿⼊ソートとその拡張5.4ヒープソート5.5クイックソート5.6マージソート5.7値の⽐較を⽤いない整列

Page 3: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

5.6マージソート①与えられたデータ𝐴を

𝐴"と𝐴#にほぼ⼆等分する.

②𝐴"と𝐴#を整列する.このとき,データ数が1であれば,整列済み.これ以外の場合, 𝐴"と𝐴#に対してマージソートの⼿続きを適⽤する.

③整列された𝐴"と𝐴#をマージする.

Page 4: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

5.6マージソート

Page 5: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

マージ処理(⼩さい⽅を出⼒する)

Page 6: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

Cプログラムの例

#include<stdio.h>

voidmerge(intA[],intleft,intmid,intright){

inti,j,k,B[right-left+1];i=left;j=mid+1;k=0;while(i<=mid&&j<=right){

if(A[i]<=A[j]){B[k++]=A[i++];

}else{B[k++]=A[j++];

}}if(i==mid+1){

while(j<=right){B[k++]=A[j++];

}}else{

while(i<=mid){B[k++]=A[i++];

}}for(i=0,j=left;j<=right;i++,j++)A[j]=B[i];

}

voidmerge_sort(intA[],intleft,intright){

intp,mid;mid=(left+right)/2;if(left<mid)merge_sort(A,left,mid);if(mid+1<right)merge_sort(A,mid+1,right);merge(A,left,mid,right);

}

voidPrintArray(intA[],intn){略}

intmain(){

intA[]={32,43,15,25,8,9,1,2,5,13};

PrintArray(A,10);merge_sort(A,0,9);PrintArray(A,10);

}

Page 7: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

5.6 マージソート•マージソートにおける時間計算量•平均時間計算量も最悪時間計算量も𝑂 𝑛 log 𝑛•整列のために同じサイズの配列がもう⼀つ必要になる.•外部整列に向いている.(コラム参照)

Page 8: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

[コラム]整列アルゴリズムの計算量の下界

•整列は要素間に成⽴する⼤⼩関係を決定すること•これは2分決定⽊で表現できる.•この決定⽊の⾼さは,𝑂(𝑛 log 𝑛)である.•これが整列アルゴリズムの下界となる.

x<y<z,x<z<y,y<x<z,y<z<x,z<x<y,z<y<x

x<y<z,x<z<y,z<x<y

y<x<z,y<z<x,z<y<x

x<y y<x

x<z

x<y<z,x<z<y,

z<x

z<x<y

y<z z<y

x<y<z x<z<y

x<z

y<x<z

z<x

y<z<x,z<y<x

y<z z<y

y<z<x z<y<x

Page 9: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

5.7 値の⽐較を⽤いない整列• 5.7.1バケットソート• 5.7.2基数ソート

Page 10: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

5.7.1バケットソート• 0〜𝑀 − 1の整数値を取るデータに対して,0〜𝑀 − 1の添え字のついた𝑀個のバケットを⽤意しておく• 整列対象のデータを1つずつ順に対応するバケットに⼊れていく• すべてのデータをバケットに⼊れ終えた時点で,バケットの内容を順番に読み出せば整列が終わる.

Page 11: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

5.7.1バケットソート同じデータを格納できるようにキューを使う

Page 12: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

Cプログラムの例

#include<stdio.h>#include<stdlib.h>#defineNum50charQueue[Num];intfront=0;intrear=0;#defineEMPTY-1

voidinit_queue(){

inti;for(i=0;i<Num;i++)Queue[i]=EMPTY;

}

intdequeue(){

if(front==rear)returnEMPTY;returnQueue[front++];

}

voidPrintArray(intA[],intn){略}

voidbucket_sort(intA[],intn){

inti,max,d;init_queue();max=A[0];for(i=0;i<n;i++){

Queue[A[i]]=A[i];if(A[i]>max)max=A[i];

}rear=max+1;i=0;while(front<rear){

d=dequeue();if(d!=EMPTY)A[i++]=d;

}}

intmain(){

intA[]={32,43,15,25,8,9,1,2,5,13};PrintArray(A,10);bucket_sort(A,10);PrintArray(A,10);

}

Page 13: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

5.7.2基数ソート• 𝑘桁の𝑟進数の場合,各桁の値は0〜𝑟 − 1である.•各桁を下の桁から順にバケットソートで整列し,順に読み出し,⼀つ上の桁のバケットソートを⾏う.

Page 14: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

Cプログラムの例

#include<stdio.h>#include<stdlib.h>#defineRadix10typedefstructcell{

intdata;structcell*next;

}Cell;Cell*Bucket[Radix];intindx;

voidInit(){

inti;for(i=0;i<Radix;i++)Bucket[i]=NULL;

}

Cell*AllocCell(intd){

Cell*rv;rv=(Cell*)malloc(sizeof(Cell));rv->data=d;rv->next=NULL;returnrv;

}

voidinsert_cell_top(Cell**H,intd){

Cell*New;New=AllocCell(d);New->next=*H;*H=New;

}

voidinsert(inta,intd){

insert_cell_top(&Bucket[a],d);}

voidrecursive_set(Cell*H,intA[]){

if(H->next!=NULL){recursive_set(H->next,A);

}A[indx++]=H->data;free(H);

}

Page 15: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

Cプログラムの例(続き)

voidread_and_set(intA[]){

inti;for(i=0;i<Radix;i++){

if(Bucket[i]!=NULL){recursive_set(Bucket[i],A);Bucket[i]=NULL;

}}

}

voidradix_sort(intA[],intn){

inti,j,r=1,flag=1;Cell*H;while(flag){

flag=0;for(i=0;i<n;i++){

insert((A[i]/r)%Radix,A[i]);if((A[i]/r)%Radix!=0)flag=1;

}if(flag==0)break;indx=0;read_and_set(A);r=r*Radix;

}}

voidPrintArray(intA[],intn){略}

intmain(){

intA[]={32,43,15,25,8,9,1,2,5,13};

PrintArray(A,10);radix_sort(A,10);PrintArray(A,10);

}

Page 16: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

プログラミング上の補⾜知識•⼀つのソートプログラムで,昇順にも,降順にも並べ替える⽅法は?•⼀つのソートプログラムで,整数も⽂字列も並べ替える⽅法は?

答え:関数のポインタを使う.次は単純挿⼊法を関数のポインタで書いた例

Page 17: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

単純挿⼊法Cプログラムの例#include<stdio.h>

voidinsertion_sort(intA[],intn){

inti,j,d;for(i=1;i<n;i++){

d=A[i];j=i-1;while((j>=0)&&(d< A[j])){

A[j+1]=A[j];j--;

}A[j+1]=d;

}}

voidPrintArray(intA[],intn){

inti;for(i=0;i<n;i++)printf("%d,",A[i]);printf("¥n");

}

intmain(){

intA[]={32,43,15,25,8,9,1,2,5,13};

PrintArray(A,10);insertion_sort(A,10);PrintArray(A,10);

}

Page 18: データ構造と アルゴリズム第13回 - 和田研究室vrl.sys.wakayama-u.ac.jp/~twada/DA/var/uploads/00003/DA13...5.6 マージソート ①与えられたデータ!を! "と!

関数ポインタを⽤いた単純挿⼊法のプログラム

#include<stdio.h>intcomp1(inta,intb){return(a<b);}intcomp2(inta,intb){return(a>b);}

voidinsertion_sort(intA[],intn, int(*cmp)(int,int)){

inti,j,d;for(i=1;i<n;i++){

d=A[i];j=i-1;while((j>=0)&&(cmp(d,A[j]))){

A[j+1]=A[j];j--;

}A[j+1]=d;

}}

voidPrintArray(intA[],intn){

inti;for(i=0;i<n;i++)printf("%d,",A[i]);printf("¥n");

}

intmain(){

intA[]={32,43,15,25,8,9,1,2,5,13};

PrintArray(A,10);insertion_sort(A,10,comp1);PrintArray(A,10);insertion_sort(A,10,comp2);PrintArray(A,10);

}

twada$./a.out32,43,15,25,8,9,1,2,5,13,1,2,5,8,9,13,15,25,32,43,43,32,25,15,13,9,8,5,2,1,