史萊姆論壇

返回   史萊姆論壇 > 專業主討論區 > 程式語言討論區
忘記密碼?
論壇說明

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


發文 回覆
 
主題工具 顯示模式
舊 2010-04-06, 03:37 AM   #1
cara4bear
註冊會員
榮譽勳章

勳章總數
UID - 338313
在線等級: 級別:0 | 在線時長:0小時 | 升級還需:5小時
註冊日期: 2010-04-04
文章: 1
精華: 0
現金: 1 金幣
資產: 1 金幣
Question 疑問 - c語言merge sort的問題

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 8; //暫設大小為8

void merge(int *data[], int length);
void mergesort(int *data[], int left, int mid, int right);

void main(void)
{
int data[] = {5,1,7,50,10,4,80,33};
int i = 0;
srand(time(NULL));
int length = SIZE;
printf("陣列大小:%d \n", length);
printf("原陣列:");
for(i = 0; i < length; i ++){//亂數產生放入陣列中
//data[i] = rand();
printf("%d ", data[i]);
}

merge(*data, length);
printf("\n排列後之陣列:");
for(i = 0; i < length; i ++){
printf("%d ", data[i]);
}
system("pause");
return(0);
}



void merge(int *data[], int length)
{
int count = 0, size = 1;//分割用
int left = 0, right = 0, mid = 0; //指標用
while(count < 5){
while(1){
mid = (left + size)-1;
right = (mid + size);
if(length <= right){
right = length - 1;
if(right <= mid){
break;}
}

mergesort(*data, left, mid, right);
left = right + 1;
printf("\n%d %d", right, mid);
}
count += 1;
size *= 2;
}

}

void mergesort(int *data[], int left, int mid, int right)
{
int temp[] = {};
int i = 0, j = left, k = left;

while(j<=mid){
temp[i] = *data[j];
i++;
j++;
}
i = 0;
while(j <= right){
if(temp[i] <= *data[j]){
*data[k] = temp[i];
k ++;
i ++;
}else{
*data[k] = *data[j];
k ++;
j ++;
}
}
while (k < j){
*data[k] = temp[i];
k = k+1; i = i+1;
}
}


想寫一個bottom-up的merge sort
但卻無法執行
應該是mergesort的副程式有問題吧
可是卻不知道到底問題出在哪> <

想請各位高手幫小女解惑

拜託各位大哥大姊了
cara4bear 目前離線  
送花文章: 0, 收花文章: 0 篇, 收花: 0 次
回覆時引用此帖
舊 2010-04-06, 09:21 PM   #2 (permalink)
註冊會員
 
pedrowong 的頭像
榮譽勳章
UID - 312366
在線等級: 級別:13 | 在線時長:250小時 | 升級還需:2小時級別:13 | 在線時長:250小時 | 升級還需:2小時級別:13 | 在線時長:250小時 | 升級還需:2小時
註冊日期: 2008-10-25
住址: 台北
文章: 94
精華: 0
現金: 207 金幣
資產: 367 金幣
預設 剔除錯誤描述結果如下

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 8; //暫設大小為8

void merge(int *data[], int length);
void mergesort(int *data[], int left, int mid, int right);

void main(void)
{
int data[] = {5,1,7,50,10,4,80,33};
int i = 0;
int length = SIZE;

srand(time(NULL));

printf("陣列大小:%d \n", length);
printf("原陣列:");
for(i = 0; i < length; i ++){//亂數產生放入陣列中
//data[i] = rand();
printf("%d ", data[i]);
}

merge(&data, length);
printf("\n排列後之陣列:");
for(i = 0; i < length; i ++){
printf("%d ", data[i]);
}
system("pause");
return;
}



void merge(int *data[], int length)
{
int count = 0, size = 1;//分割用
int left = 0, right = 0, mid = 0; //指標用

while(count < 5){
while(1){
mid = (left + size)-1;
right = (mid + size);
if(length <= right){
right = length - 1;
if(right <= mid){break;}
}

mergesort(data, left, mid, right);
left = right + 1;
printf("\n%d %d", right, mid);
}
count += 1;
size *= 2;
}

}

void mergesort(int *data[], int left, int mid, int right)
{
int temp[8];
int i = 0, j = left, k = left;

while(j<=mid){
temp[i] = data[j];
i++;
j++;
}
i = 0;
while(j <= right){
if(temp[i] <= data[j]){
data[k] = temp[i];
k ++;
i ++;
}else{
data[k] = data[j];
k ++;
j ++;
}
}
while (k < j){
data[k] = temp[i];
k = k+1; i = i+1;
}
}
pedrowong 目前離線  
送花文章: 4, 收花文章: 84 篇, 收花: 193 次
回覆時引用此帖
舊 2010-04-06, 09:21 PM   #3 (permalink)
管理員
 
getter 的頭像
榮譽勳章
UID - 6433
在線等級: 級別:96 | 在線時長:9733小時 | 升級還需:64小時級別:96 | 在線時長:9733小時 | 升級還需:64小時級別:96 | 在線時長:9733小時 | 升級還需:64小時級別:96 | 在線時長:9733小時 | 升級還需:64小時級別:96 | 在線時長:9733小時 | 升級還需:64小時級別:96 | 在線時長:9733小時 | 升級還需:64小時
註冊日期: 2002-12-08
住址: 天線星球
文章: 8157
精華: 0
現金: 19955 金幣
資產: 765391 金幣
預設

錯誤一:void mergesort(int *data[], int left, int mid, int right)

當 void mergesort(int *data[], int left, int mid, int right)
有 * 號指標變數不宜同時使用有 [] 號,某些編譯器會出錯。

* 號的作用與 & 的作用相當都只做記憶體位址的轉換與呼叫 ...

這樣就能直接存取上層的變數了不然一般的

void mergesort(int data[],int left, int mid, int right)

意旨開個專櫃去接受外來的資料,當資料改變時也是只有這個專櫃
改變而已,並不會影響的上層宣告 data。動來動去都是 () 內的
宣告的變數。

若是要直接存取上層的變數的資料,就要透過 * 號指標變數,
其實指標變數的作用就是直接存取上層宣告 data,這是就能存取
原先的變數內容了。

void mergesort(int *data,int left, int mid, int right)


錯誤二 {} 內的 *
語法:
void mergesort(int *data, int left, int mid, int right)
{ 
int temp[] = {};
int i = 0, j = left, k = left;

while(j<=mid){
temp[i] = *data[j];
i++;
j++;
}

i = 0;
while(j <= right){
if(temp[i] <= *data[j]){
*data[k] = temp[i];
k ++;
i ++;
}else{
*data[k] = *data[j];
k ++;
j ++;
}
}

while (k < j){
*data[k] = temp[i];
k = k+1; i = i+1; 
}

}
當副程式的宣告 void mergesort(int *data, int left, int mid, int right)
已經做好了銜接時,就可以直接依照原來的陣列語法直接操作資料的演算,無須
在加 * 號了,若要使用 * 號的話要以指標變數的對應操作的方式進行處理如下

data[0] 對應到 *data 或 *(data+0)
data[1] 對應到 *(data+1)
data[2] 對應到 *(data+2)



錯誤三 mergesort 副程式中的 int temp[] = {};
語法:
void mergesort(int *data, int left, int mid, int right)
{ 
int temp[] = {};
int i = 0, j = left, k = left;

while(j<=mid){
temp[i] = data[j];
i++;
j++;
}

i = 0;
while(j <= right){
if(temp[i] <= data[j]){
data[k] = temp[i];
k ++;
i ++;
}else{
data[k] =data[j];
k ++;
j ++;
}
}

while (k < j){
data[k] = temp[i];
k = k+1; i = i+1; 
}

}
這樣的陣列宣告是錯誤的,會生一個邏輯的錯誤,可能變成只有
1 個長度的陣列 ... 當後方程式語法使用是大於 1 個長度的陣
列,就會發生錯誤了,宣告陣列一定要有大小,不然就由資料大
小做陣列的大小做調整。當然某些編譯器會當作是語法的錯誤而
不執行。


錯誤四 merge、mergesort 副程式可能有種邏輯錯誤

依據 merge、mergesort 的程式來看,其程式結果可能是整個排序
的結果可能是兩兩一組的前後對換而已,如下

排序前 5, 1, 7,50,10, 4,80,33
排序後 1, 5, 7,50, 4,10,33,80

若是要做到這種排序效果可以將程式化簡如下:
語法:
void merge(int *data, int length)
{
int i; 
for(i=0;i<length;i+=2){
mergesort(data, i, i+1);
printf("\n right=%d ,mid=%d", i+1, i);} 
}

void mergesort(int *data, int mid, int right)
{ 
int temp;
if(data[mid] > data[right]){
temp = data[mid];
data[mid] = data[right];
data[right] = temp;} 
}
可以進一步的合併成
語法:
void mergesort(int *data, int length)
{
int i,temp;
for(i=0;i<length;i+=2){
if(data[i] > data[i+1]){
temp = data[i];
data[i] = data[i+1];
data[i+1] = temp;} 
printf("\n right=%d ,mid=%d", i+1, i);} 
}
最後如下:
語法:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 8; //暫設大小為8

void mergesort(int *data, int length);

void main(void)
{
int data[] = {5,1,7,50,10,4,80,33};
int i = 0;
int length = SIZE; 

printf("陣列大小: %d \n",length);
printf("原陣列:");

for(i = 0; i < length; i ++){//亂數產生放入陣列中 
//data[i] = rand();
printf("%d ", data[i]);}

mergesort(data, length);

printf("\n排列後之陣列:");
for(i = 0; i < length; i ++){ 
printf("%d ", data[i]);}

printf("\n\n");
system("pause");
}


void mergesort(int *data, int length)
{
int i,temp;
for(i=0;i<length;i+=2){
if(data[i] > data[i+1]){
temp = data[i];
data[i] = data[i+1];
data[i+1] = temp;} 
printf("\n right=%d ,mid=%d", i+1, i);} 
}

此帖於 2010-04-06 09:35 PM 被 getter 編輯.
__________________
在「專業主討論區」中的問題解決後,要記得按一下 http://forum.slime.com.tw/images/stamps/is_solved.gif 按鈕喔,
這是一種禮貌動作。

一樣是在「專業主討論區」中發問,不管問題解決與否,都要回應別人的回答文喔。
不然搞 [斷頭文],只看不回應,下次被別人列入黑名單就不要怪人喔。

天線寶寶說再見啦~ ... 天線寶寶說再見啦~

迪西:「再見~ 再見~」

Otaku Culture Party 關心您 ...
getter 目前離線  
送花文章: 37855, 收花文章: 6441 篇, 收花: 26052 次
回覆時引用此帖
舊 2010-07-17, 02:08 AM   #4 (permalink)
長老會員
 
cwvdavid 的頭像
榮譽勳章
UID - 476
在線等級: 級別:46 | 在線時長:2395小時 | 升級還需:2小時級別:46 | 在線時長:2395小時 | 升級還需:2小時級別:46 | 在線時長:2395小時 | 升級還需:2小時級別:46 | 在線時長:2395小時 | 升級還需:2小時級別:46 | 在線時長:2395小時 | 升級還需:2小時級別:46 | 在線時長:2395小時 | 升級還需:2小時
註冊日期: 2002-12-06
住址: 天與地的夾縫
文章: 3106
精華: 0
現金: 5256 金幣
資產: 2034465 金幣
預設

已經是斷頭文了...
__________________
姜太公釣魚~ 願者上鉤
cwvdavid 目前離線  
送花文章: 4036, 收花文章: 2466 篇, 收花: 10141 次
回覆時引用此帖
發文 回覆



發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用

相似的主題
主題 主題作者 討論區 回覆 最後發表
撥放軟體語言轉換的問題.... ECKO 一般電腦疑難討論區 4 2003-09-09 11:03 AM
問一個組合語言的問題 turnoff 一般電腦疑難討論區 0 2003-07-28 09:34 AM
請問要看日.韓語言網頁的問題? kana6468 一般電腦疑難討論區 1 2003-06-13 12:51 PM
c語言撰寫的問題(鏈結陣列) hugo0820 軟體應用問題討論區 0 2003-05-26 10:14 AM
請問xp繁體語言包的問題.... 721017 一般電腦疑難討論區 3 2003-04-27 02:38 PM


所有時間均為台北時間。現在的時間是 09:59 AM


Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2024, Jelsoft Enterprises Ltd.


SEO by vBSEO 3.6.1