第11章 基礎實驗程式碼
阿新 • • 發佈:2020-11-04
目錄
實驗1-線性表的順序實現
- lab1_01_ans.c
/**********************************/ /*檔名稱:lab1-01.c */ /**********************************/ /*基於sequlist.h中定義的順序表,編寫演算法函式reverse(sequence_list *L),實現順序表的就地倒置。*/ #include "sequlist.h" /*請將本函式補充完整,並進行測試*/ void reverse(sequence_list *L) { int i,j; datatype x; i=0; j=L->size-1; while (i<j) { x=L->a[i]; L->a[i]=L->a[j]; L->a[j]=x; i++; j--; } }
- lab1_02_ans.c
/**********************************/ /*檔名稱:lab1_02.c */ /**********************************/ /*編寫一個演算法函式void sprit( sequence_list *L1,sequence_list *L2,sequence_list *L3), 將順序表L1中的資料進行分類,奇數存放到存到順序表L2中,偶數存到順序表L3中,編寫main()進行測試。 */ #include "sequlist.h" /*請將本函式補充完整,並進行測試*/ void sprit(sequence_list *L1,sequence_list *L2,sequence_list *L3) { int i,j,k; i=j=k=0; for (i=0;i<L1->size;i++) { if (L1->a[i]%2==1) L2->a[j++]=L1->a[i]; else L3->a[k++]=L1->a[i]; } L2->size=j; L3->size=k; }
- lab1_03_ans.c
/*已知順序表L1,L2中資料由小到大有序,請用盡可能快的方法將L1與L2中的資料合併到L3中,使資料在L3中按升序排列。*/ #include "sequlist.h" /*請將本函式補充完整,並進行測試*/ void merge(sequence_list *L1,sequence_list *L2,sequence_list *L3) { int i,j,k; i=j=k=0; while (i<L1->size && j<L2->size ) { if (L1->a[i]<L2->a[j]) L3->a[k++]=L1->a[i++]; else L3->a[k++]=L2->a[j++]; } while (i<L1->size) L3->a[k++]=L1->a[i++]; while (j<L2->size) L3->a[k++]=L2->a[j++]; L3->size=k; }
- lab1_04_ans.c
/*假設順序表la與lb分別存放兩個整數集合,函式inter(seqlist *la,seqlist *lb,seqlist *lc)
的功能是實現求順序表la與lb的交集存放到順序表lc中,請將函式補充完整. */
/**********************************/
/*檔名稱:lab1_04.c */
/**********************************/
#include "sequlist.h"
/*請將本函式補充完整,並進行測試*/
void inter(sequence_list *la,sequence_list *lb,sequence_list *lc)
{
int i,j,k;
k=0;
for (i=0; i<la->size; i++)
{
j=0;
while (j<lb->size && la->a[i]!=lb->a[j])
j++;
if (j<lb->size)
lc->a[k++]=la->a[i];
}
lc->size=k;
}
- lab1_05_ans.c
/*
請編寫一個演算法函式partion(sequence_list *L),儘可能快地將順序表L中的所有奇數調整到表的左邊,
所有偶數調整到表的右邊,並分析演算法的時間複雜度。
*/
/**********************************/
/*檔名稱:lab1_05.c */
/**********************************/
#include "sequlist.h"
/*請將本函式補充完整,並進行測試*/
void partion(sequence_list *L)
{
int i,j;
datatype x;
i=0;
j=L->size-1;
do
{
while (i<j && L->a[i]%2==1 )
i++;
while (i<j && (L->a[j]&0x1)==0)
j--;
if (i<j)
{
x=L->a[i];
L->a[i++]=L->a[j];
L->a[j--]=x;
}
}while (i<j);
}
實驗2-不帶頭結點的單鏈表
- lab2_01_ans.c
/*編寫函式slnklist delx(linklist head, datatype x),刪除不帶頭結點單鏈表head中第一個值為x 的結點。
並構造測試用例進行測試。
*/
/**********************************/
/*檔名稱:lab2_01.c */
/**********************************/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
linklist delx(linklist head,datatype x)
{
linklist pre,p;
pre=NULL;
p=head;
while (p &&p->info!=x)
{
pre=p;
p=p->next;
}
if (p)
{
if (pre==NULL)
head=p->next;
else
pre->next=p->next;
free(p);
}
return head;
}
- lab2_02_ans.c
/**********************************/
/*檔名稱:lab2_02.c */
/**********************************/
/*
假設線性表(a1,a2,a3,…an)採用不帶頭結點的單鏈表儲存,
請設計演算法函式linklist reverse1(linklist head)和
void reverse2(linklist *head)將不帶頭結點的單鏈表head就地倒置,
使表變成(an,an-1,…a3.a2,a1)。並構造測試用例進行測試。
*/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
linklist reverse1(linklist head)
{
linklist p,s;
p=head;
head=NULL;
while (p)
{
s=p;
p=p->next;
s->next=head;
head=s;
}
return head;
}
void reverse2(linklist *head)
{
linklist p,s;
p=*head;
*head=NULL;
while (p)
{
s=p;
p=p->next;
s->next=*head;
*head=s;
}
}
- lab2_03_ans.c
/*
假設不帶頭結點的單鏈表head是升序排列的,設計演算法函式linklist insert(linklist head,datatype x),
將值為x的結點插入到連結串列head中,並保持連結串列有序性。
分別構造插入到表頭、表中和表尾三種情況的測試用例進行測試。
*/
/**********************************/
/*檔名稱:lab2_03.c */
/**********************************/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
linklist insert(linklist head ,datatype x)
{
linklist pre,p,s;
pre=NULL;
p=head;
while ( p && p->info<x )
{
pre=p;
p=p->next;
}
s=(linklist )malloc(sizeof(node));
s->info=x;
if (pre==NULL)
{
s->next=head;
head=s;
}
else
{
s->next=p;
pre->next=s;
}
return head;
}
- lab2_04_ans.c
/*
編寫演算法函式linklist delallx(linklist head, int x),刪除不帶頭結點單鏈表head中所有值為x的結點。
*/
/**********************************/
/*檔名稱:lab2_04.c */
/**********************************/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
linklist delallx(linklist head,int x)
{
linklist pre,p;
pre=NULL;
p=head;
while(p)
{
while (p &&p->info!=x) //找值為x的結點
{
pre=p;
p=p->next;
}
if (p) //找到了
{
if (pre==NULL) //刪除的結點為第一個結點
{
head=p->next;
free(p);
p=head;
}
else //刪除的結點不是第一個結點
{
pre->next=p->next;
free(p);
p=pre->next;
}
}
}
return head;
}
實驗3-帶頭結點的單鏈表
- lab3_01_ans.c
/*編寫函式void delx(linklist head, datatype x),刪除帶頭結點單鏈表head中第一個值為x 的結點。
並構造測試用例進行測試。
*/
/**********************************/
/*檔名稱:lab3_01.c */
/**********************************/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
void delx(linklist head,datatype x)
{
linklist pre,p;
pre=head;
p=head->next;
while (p && p->info!=x) //查詢
{
pre=p;
p=p->next;
}
if (p) //刪除
{
pre->next=p->next;
free(p);
}
}
- lab3_02_ans.c
/**********************************/
/*檔名稱:lab3_02.c */
/**********************************/
/*
假設線性表(a1,a2,a3,…an)採用帶頭結點的單鏈表儲存,請設計演算法函式void reverse(linklist head),
將帶頭結點的單鏈表head就地倒置,使表變成(an,an-1,…a3.a2,a1)。並構造測試用例進行測試。
*/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
void reverse(linklist head)
{
linklist p,s;
p=head->next;
head->next=NULL;
while (p)
{
s=p;
p=p->next;
s->next=head->next;
head->next=s;
}
}
- lab3_03_ans.c
/*
假設帶頭結點的單鏈表head是升序排列的,設計演算法函式linklist insert(linklist head,datatype x),
將值為x的結點插入到連結串列head中,並保持連結串列有序性。
分別構造插入到表頭、表中和表尾三種情況的測試用例進行測試。
*/
/**********************************/
/*檔名稱:lab3_03.c */
/**********************************/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
void insert(linklist head ,datatype x)
{
linklist pre,p,s;
pre=head;
p=head->next;
while (p && p->info<x)
{
pre=p;
p=p->next;
}
s=(linklist)malloc(sizeof(node));
s->info=x;
s->next=p;
pre->next=s;
}
- lab3_04_ans.c
/*
編寫演算法函式void delallx(linklist head, int x),刪除帶頭結點單鏈表head中所有值為x的結點。
*/
/**********************************/
/*檔名稱:lab3_04.c */
/**********************************/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
void delallx(linklist head,int x)
{
linklist pre,p;
pre=head;
p=head->next;
while(p)
{
while (p &&p->info!=x) //查詢
{
pre=p;
p=p->next;
}
if (p) //找到了
{
pre->next=p->next;
free(p);
p=pre->next; //刪除後p回到pre的後繼結點
}
}
}
- lab3_05_ans.c
/*
已知線性表儲存在帶頭結點的單鏈表head中,請設計演算法函式void sort(linklist head),將head中的結點按結點值升序排列。
*/
/**********************************/
/*檔名稱:lab3_05.c */
/**********************************/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
void sort(linklist head)
{
linklist pre,q,p,s;
p=head->next;
head->next=NULL;
while (p)
{
s=p;
p=p->next; //取結點
pre=head;
q=head->next;
while (q && q->info<s->info) //找位置
{
pre=q;
q=q->next;
}
s->next=q; //將s指示的結點插入到pre與q指示的結點中間
pre->next=s;
}
}
- lab3_06_ans.c
/*
已知兩個帶頭結點的單鏈表L1和L2中的結點值均已按升序排序,設計演算法函式
linklist mergeAscend (linklist L1,linklist L2)將L1和L2合併成一個升序的
帶頭結單鏈表作為函式的返回結果;
設計演算法函式linklist mergeDescend (linklist L1,linklist L2)
將L1和L2合併成一個降序的帶頭結單鏈表作為函式的返回結果;
並設計main()函式進行測試。
*/
/**********************************/
/*檔名稱:lab3_06.c */
/**********************************/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
linklist mergeAscend(linklist L1,linklist L2)
{
linklist L3,r3,p,q;
L3=r3=(linklist)malloc(sizeof(node));
p=L1->next;
q=L2->next;
while (p && q)
{
if (p->info<q->info)
{
L1->next=p->next;
r3->next=p;
r3=p;
p=L1->next;
}
else
{
L2->next=q->next;
r3->next=q;
r3=q;
q=L2->next;
}
}
if (p) r3->next=p;
if (q) r3->next=q;
free(L1);
free(L2);
return L3;
}
linklist mergeDescend(linklist L1,linklist L2)
{
linklist L3,r3,p,q;
L3=(linklist)malloc(sizeof(node));
L3->next=NULL;
p=L1->next;
q=L2->next;
while (p && q)
{
if (p->info<q->info)
{
L1->next=p->next;
p->next=L3->next;
L3->next=p;
p=L1->next;
}
else
{
L2->next=q->next;
q->next=L3->next;
L3->next=q;
q=L2->next;
}
}
while (p)
{
L1->next=p->next;
p->next=L3->next;
L3->next=p;
p=L1->next;
}
while (q)
{
L2->next=q->next;
q->next=L3->next;
L3->next=q;
q=L2->next;
}
free(L1);
free(L2);
return L3;
}
- lab3_07_ans.c
/*
設計一個演算法linklist interSection(linklist L1,linklist L2),
求兩個單鏈表表示的集合L1和L2的交集,並將結果用一個新的帶頭
結點的單鏈表儲存並返回表頭地址。
*/
/**********************************/
/*檔名稱:lab3_07.c */
/**********************************/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
linklist interSection(linklist L1, linklist L2)
{
linklist head,r,p,q,s;
head=r=(linklist)malloc(sizeof(node));
p=L1->next;
while (p)
{
q=L2->next;
while (q && q->info!=p->info)
q=q->next;
if (q)//查詢成功
{
s=(linklist)malloc(sizeof(node));
s->info=p->info;
r->next=s;
r=s;
}
p=p->next;
}
r->next=NULL;
return head;
}
- lab3_08_ans.c
/*
請編寫一個演算法函式void partion(linklist head),
將帶頭結點的單鏈表head中的所有值為奇數的結點調整
到連結串列的前面,所有值為偶數的結點調整到連結串列的後面。
*/
/**********************************/
/*檔名稱:lab3_08.c */
/**********************************/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
void partion(linklist head)
{
linklist pre,p;
pre=head;
p=head->next;
while (p &&p->info%2==1)
{
pre=p;
p=p->next;
}
while (p)
{
while (p &&p->info%2==0)
{
pre=p;
p=p->next;
}
if (p)
{
pre->next=p->next;
p->next=head->next;
head->next=p;
p=pre->next;
}
}
}
- lab3_09_ans.c
/*
編寫一個程式,用盡可能快的方法返回帶頭結點單鏈表中倒數第k個結點的地址,如果不存在,則返回NULL。
*/
/**********************************/
/*檔名稱:lab3_09.c */
/**********************************/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
linklist search(linklist head,int k)
{
linklist pre,p;
int count=0;
p=head->next;
while (p && count<k)
{
p=p->next;
count++;
}
if (count<k) return NULL;
pre=head->next;
while (p)
{
pre=pre->next;
p=p->next;
}
return pre;
}
實驗4-棧與字串
- lab4_01_ans.c
/*
利用順序棧結構,編寫演算法函式void Dto16(unsigned int m)實現十進位制無符號整數m到十六進位制數的轉換功能。
*/
/**********************************/
/*檔名稱:lab4_01.c */
/**********************************/
#include "seqstack.h"
/*請將本函式補充完整,並進行測試*/
void Dto16(int m)
{ seqstack s; /*定義順序棧*/
init(&s);
printf("十進位制數%u對應的十六進位制數是:",m);
while (m)
{
push(&s,m%16);
m/=16;
}
while (!empty(&s))
putchar( read(&s)<10? pop(&s)+48: pop(&s)+55 );
printf("\n");
}
- lab4_02_ans.c
/*
利用鏈式棧結構,編寫演算法函式void Dto16(unsigned int m)實現十進位制無符號整數m到十六進位制數的轉換功能。
*/
/**********************************/
/*檔名稱:lab4_02.c */
/**********************************/
#include "linkstack.h"
/*請將本函式補充完整,並進行測試*/
void Dto16(unsigned int m)
{
linkstack s;
s=init();
printf("十進位制數%u對應的十六進位制數是:",m);
while (m)
{
s=push(s,m%16);
m/=16;
}
while (!empty(s))
{
printf("%x", read(s));
s=pop(s);
}
printf("\n");
}
- lab4_04_ans.c
/*
已知字串採用帶結點的鏈式儲存結構(詳見linksrting.h檔案),
請編寫函式linkstring substring(linkstring s,int i,int len),
在字串s中從第i個位置起取長度為len的子串,函式返回子串連結串列。
*/
#include "linkstring.h"
/*請將本函式補充完整,並進行測試*/
linkstring substring(linkstring s, int i, int len)
{
linkstring head,r,q,p;
int k=1;
head=r=(linkstring)malloc(sizeof(linknode));
r->next=NULL;
p=s->next;
while (p && k<i) //找子串起點
{
p=p->next;
k++;
}
if (!p) return head; //起點超過連結串列長度
else
{
k=1;
while (p && k<=len) //生成子串連結串列
{
q=(linkstring)malloc(sizeof(linknode));
q->data=p->data;
r->next=q;
r=q;
p=p->next;
k++;
}
r->next=NULL;
return head;
}
}
- lab4_05_ans.c
/*
字串採用帶頭結點的連結串列儲存,設計演算法函式void delstring(linkstring s, int i,int len)
在字串s中刪除從第i個位置開始,長度為len的子串。
*/
/**********************************/
/*檔名稱:lab4_05.c */
/**********************************/
#include "linkstring.h"
/*請將本函式補充完整,並進行測試*/
void delstring(linkstring s, int i, int len)
{
linkstring p,q;
int k=1;
p=s->next;
while (p && k<i-1) //查詢待刪除子串的起始結點的前驅結點
{
p=p->next;
k++;
}
if (!p || !p->next) return ;
else
{
k=0;
while (p->next && k<len)
{
q=p->next;
p->next=q->next;
free(q);
k++;
}
}
}
- lab4_06_ans.c
/*
字串採用帶頭結點的連結串列儲存,編寫函式linkstring index(linkstring s, linkstring t),
查詢子串t在主串s中第一次出現的位置,若匹配不成功,則返回NULL。
*/
#include "linkstring.h"
/*請將本函式補充完整,並進行測試*/
linkstring index(linkstring s, linkstring t)
{
linkstring p,s1,t1;
p=s->next;
while (p) //p記錄匹配起點
{
s1=p; //s1記錄主串比較的當前位置
t1=t->next; //t1記錄子串比較的當前位置
while (s1 && t1 && s1->data==t1->data)
{
s1=s1->next;
t1=t1->next;
}
if (t1==NULL) return p;
p=p->next;
}
return NULL;
}
- lab4_07_ans.c
/*
利用樸素模式匹配演算法,將模式t在主串s中所有出現的位置儲存在帶頭結點的單鏈表中。
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{ int data;
struct node *next;
}linknode;
typedef linknode *linklist;
/*樸素模式匹配演算法,返回t中s中第一次出現的位置,沒找到則返回-1,請將程式補充完整*/
int index(char *s,char *t)
{ int i,k,j;
int n,m;
n=strlen(s);
m=strlen(t);
for (i=0;i<n-m+1;i++)
{
k=i;
j=0;
while (j<m)
{
if (s[k]==t[j]) {k++;j++;}
else
break;
}
if (j==m) return i;
}
return -1;
}
/*利用樸素模式匹配演算法,將模式t在s中所有出現的位置儲存在帶頭結點的單鏈表中,請將函式補充完整*/
linklist indexall(char *s,char *t)
{
linklist head,r,p;
int i,k,j;
int n,m;
n=strlen(s);
m=strlen(t);
head=r=(linklist)malloc(sizeof(linknode));
for (i=0;i<n-m+1;i++)
{
k=i;
j=0;
while (j<m)
{
if (s[k]==t[j]) {k++;j++;}
else
break;
}
if (j==m) //匹配成功
{
p=(linklist)malloc(sizeof(linknode));
p->data=i;
r->next=p;
r=p;
}
}
r->next=NULL;
return head;
}
/*輸出帶頭結點的單鏈表*/
void print(linklist head)
{ linklist p;
p=head->next;
while(p)
{ printf("%5d",p->data);
p=p->next;
}
printf("\n");
}
- lab4_08_ans.c
/*
編寫快速模式匹配KMP演算法,請將相關函式補充完整。
*/
#define maxsize 100
typedef struct{
char str[maxsize];
int length ;
} seqstring;
/*求模式p的next[]值,請將函式補充完整*/
void getnext(seqstring p,int next[])
{
int i,j;
next[0]=-1;
i=0;j=-1;
while(i<p.length)
{
if(j==-1||p.str[i]==p.str[j])
{++i;++j;next[i]=j;}
else
j=next[j];
}
for(i=0;i<p.length;i++)
printf("%d",next[i]);
}
/*快速模式匹配演算法,請將函式補充完整*/
int kmp(seqstring t,seqstring p,int next[])
{
int i,j;
i=0;j=0;
while (i<t.length && j<p.length)
{
if(j==-1||t.str[i]==p.str[j])
{i++; j++;}
else j=next[j];
}
if (j==p.length) return (i-p.length);
else return(-1);
}
實驗5-遞迴
- lab5_01_ans.c
/*
編寫遞迴演算法int max(int a[],int left, int right),求陣列a[left..right]中的最大數。
*/
#include "ArrayIo.h"
/*請將本函式補充完整,並進行測試*/
int max(int a[],int left,int right)
{
int lmax,rmax,mid;
if (left==right) return a[left];
else
{
mid=(left+right)/2;
lmax=max(a,left,mid);
rmax=max(a,mid+1,right);
return lmax>rmax?lmax:rmax;
}
}
- lab5_02_ans.c
/*
請編寫一個遞迴演算法函式void partion(int a[], int left, int right),
將陣列a[left..right]中的所有奇數調整到表的左邊,所有偶數調整到表的右邊。
*/
#include "ArrayIo.h"
#define N 10
/*請將本函式補充完整,並進行測試*/
void partion(int a[], int left,int right)
{
int x;
if (left<right)
{
while (left<right && a[left]%2==1)
left++;
while (left<right && a[right]%2==0)
right--;
if (left<right)
{
x=a[left];
a[left]=a[right];
a[right]=x;
partion(a,left+1,right-1);
}
}
}
- lab5_03_ans.c
/*
請編寫遞迴函式void bubbleSort(int a[],int n),
對長度為n的陣列採用冒泡法進行升序排序。
請編寫遞迴函式int binSearch(int a[], int left, int right,int key),
採用二分查詢法在陣列a[left..right]中查詢值為key的元素所在的位置,
若查詢失敗函式返回-1。
*/
#include "ArrayIo.h"
#define N 10
/*請將本函式補充完整,並進行測試*/
void bubbleSort(int a[],int n)
{ int i,t;
int flag;
if(n>0)
{
flag=0;
for(i=0;i<n-1;i++)
{
if(a[i]>a[i+1])
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
flag=1;
}
}
if (flag==1) bubbleSort(a,n-1);
}
return ;
}
int binSearch(int a[], int left,int right,int key)
{
int mid;
if (left>right)
return -1;
else
{
mid=(left+right)/2;
if (a[mid]==key)
return mid;
else
if (key<a[mid])
return binSearch(a,left,mid-1,key);
else
return binSearch(a,mid+1,right,key);
}
}
- lab5_04_ans.c
/*
已知帶頭結點的單鏈表結構定義同實驗3,假設連結串列中所有結點值均不相同,
請編寫一個遞迴函式linklist max(linklist head),返回表中最大數所在的結點地址,若連結串列為空,返回NULL。
*/
#include "slnklist.h"
/*請將本函式補充完整,並進行測試*/
linklist max(linklist head)
{
linklist m;
if (head->next==NULL)
return NULL;
else
if (head->next->next==NULL)
return head->next;
else
{
m=max(head->next);
return head->next->info > m->info ? head->next:m;
}
}
實驗6-樹
- lab6_01_ans.c
/*
編寫演算法函式void levelorder(tree t)實現樹的層次遍歷。
*/
#include "tree.h"
void levelorder(tree t) /* t為指向樹根結點的指標*/
{
tree queue[MAXLEN]; /*用佇列存放待處理的結點*/
int head=0,end=1;
int i;
queue[head] = t; /*先將根節點入隊*/
while( head < end )
{
for(i=0;i<m;i++) /*將佇列中結點的下一層結點入隊,逐層入隊*/
{
if( queue[head]->child[i] )
{
queue[end++] = queue[head]->child[i];
}
}
printf("%c",queue[head++]->data); /*逐層出隊*/
}
}
int main()
{
tree t;
printf("please input the preorder sequence of the tree:\n");
t=createtree();
printf("\nthe levelorder is:");
levelorder(t);
return 0;
}
- lab6_02_ans.c
/*
假設樹採用指標方式的孩子表示法表示,試編寫一個非遞迴函式void PreOrder1(tree root),實現樹的前序遍歷演算法。
*/
#include "tree.h"
void PreOrder1(tree root)
{
tree stack[100];
int i;
int top=-1;
while (root || top!=-1)
{
if (root)
{
printf("%c",root->data); //輸出根結點
for (i=m-1;i>0;i--) //所有非空孩子結點進棧
if (root->child[i]!=NULL)
{
top++;
stack[top]=root->child[i];
}
root=root->child[0]; //轉第1棵子樹
}
else
{
root=stack[top--]; //棧頂樹出棧
}
}
}
int main ()
{
tree root;
printf("please input the preorder sequence of the tree:\n");
root =createtree();
printf("前序序列是:\n");
PreOrder1(root);
return 0;
}
- lab6_03_ans.c
/*
假設樹採用指標方式的孩子表示法表示,試編寫一個非遞迴函式void PostOrder1(tree t),實現樹的後序遍歷演算法。
*/
#include "tree.h"
int PostOrder1(tree root)
{
tree treeStack[MAXLEN]; /*儲存待處理的結點*/
int top = -1;
tree printStack[MAXLEN]; /*儲存已經處理完子樹的、待輸出的結點*/
int topp = -1;
int i;
if( root ) treeStack[++top] = root; /*根結點進棧*/
while( top != -1 )
{
root = treeStack[top--]; /*取一個待處理結點root*/
for(i=0;i<m;i++) /*將root的所有子結點進棧*/
{
if( root->child[i] ) treeStack[++top] = root->child[i];
}
printStack[++topp] = root; /*處理完root、將root進printStack*/
}
while( topp != -1 ) printf("%c",printStack[topp--]->data); /*輸出後序序列*/
}
int PostOrder2(tree root)
{
tree treeStack[MAXLEN]; /*未處理完的結點*/
int subStack[MAXLEN]; /*正在處理的孩子的下標*/
int top = -1;
tree p;
int i;
treeStack[++top] = root;
subStack[top] = 0; /*首先處理child[0]這個分支*/
while( top != -1 )
{
p = treeStack[top];
while( subStack[top] < m ) /*處理所有分支*/
{
i = subStack[top];
if( p->child[i] )
{
p = p->child[i];
treeStack[++top] = p; /*有孩子則入棧*/
subStack[top] = 0; /*並處理剛入棧結點的child[0]*/
}
else {
subStack[top]++; /*該分支沒有孩子,處理下一分支*/
}
}
printf("%c",p->data); /*出棧前再輸出*/
top--; /*該結點處理完畢,返回處理父結點的child[i+1]*/
subStack[top]++;
}
}
int main ()
{ //AB###CE###FH###I####G###D### ,測試三度樹
tree root;
printf("please input the preorder sequence of the tree:\n");
root =createtree();
printf("後序序列是:\n");
PostOrder1(root);
putchar('\n');
PostOrder2(root);
return 0;
}
- lab6_04_ans.c
/*
假設樹採用指標方式的孩子表示法表示,試編寫一個函式int equal(tree t1, tree t2),
判斷兩棵給定的樹是否等價(兩棵樹等價當且僅當其根結點的值相等且其對應的子樹均相互等價)。
*/
#include "tree.h"
#define TRUE 1
#define FALSE 0
int equal(tree t1,tree t2)
{
int flag=TRUE,i;
if (t1==NULL && t2==NULL)
return TRUE;
else
if (t1==NULL && t2!=NULL || t2==NULL && t1!=NULL)
return FALSE;
else
if (t1->data!=t2->data) return FALSE;
else
{
for (i=0;i<m;i++)
flag=flag&&equal(t1->child[i],t2->child[i]);
return flag;
}
}
int main ()
{
tree t1,t2;
printf("please input the preorder sequence of the tree:\n");
t1=createtree();
getchar();
printf("please input the preorder sequence of the tree:\n");
t2=createtree();
if ( equal(t1,t2) == TRUE)
{
printf ("兩樹相等\n");
}
else
{
printf ("兩樹不相等\n");
}
return 0;
}
- lab6_05_ans.c
/*
假設樹採用指標方式的孩子表示法儲存結構,試編寫一個函式tree Ct(char s[]),
根據輸入的樹的括號表示字串s,生成樹的儲存結構。例如,若要建立教材圖6.4所示的樹,
應輸入A(B(E,F),C,D(G(I,J,K),H))。(說明,tree.h中定義的常量m表示樹的最
大度,請根據建樹的需要自行修改m的值)
*/
#include "tree.h"
/*請將本函式補充完整,並進行測試*/
tree Ct(char s[MAXLEN])
{
int length;
int i,j,top;
tree stack[100],root=NULL,temp = NULL,n;
int childSeq[m]; // 其第幾個孩子
top = -1;
length = strlen (s);
for (i = 0;i < length;i++)
{
if (s[i] == ',')
{
continue;
}
else if (s[i] == '(')
{
stack[++top] = temp;
childSeq[top] = 0;
}
else if (s[i] == ')')
{
top--;
}
else if (top != -1)
{
n = (tree)malloc (sizeof (node));
n->data= s[i];
for (j = 0;j < m;j++)
{
n->child[j] = NULL;
}
temp = n;
stack[top]->child[childSeq[top]++] = temp;
}
else
{
root = (tree)malloc (sizeof (node));
root->data = s[i];
for (j = 0;j < m;j++)
{
root->child[j] = NULL;
}
temp = root;
}
}
return root;
}
int main ()
{
char s[MAXLEN];
tree root = NULL;
printf ("請用樹的括號表示法輸入一棵樹:\n");
scanf ("%s",s);
root = Ct(s);
preorder(root); /*前序遍歷樹*/
return 0;
}
實驗7-二叉樹
- lab7_01_ans.c
/*
編寫演算法函式void preorder1(bintree t)實現二叉樹t的非遞迴前序遍歷。
*/
#include "bintree.h"
char *a="ABC##D#E##F##"; /*擴充二叉樹序樹t的前序序列*/
/*函式preorder1()的功能是非遞迴前序遍歷二叉樹t,請將函式補充完整並除錯執行*/
void preorder1(bintree t)
{
seqstack s;
init(&s);
while ( !empty(&s) || t )
{
if (t)
{
printf("%c",t->data);
push(&s, t);
t=t->lchild;
}
else
{
t=pop(&s);
t=t->rchild;
}
}
}
- lab7_02_ans.c
/*
編寫演算法函式void levelbintree(bintree t),實現二叉樹的層次遍歷。
*/
#include "bintree.h"
char *a="ABC##D#E##F##"; /*擴充二叉樹序樹t的前序序列*/
void levelbintree(bintree t)
{
bintree queue[100];
int f,r;
f=0;r=1;
if (t)
{
queue[0]=t;
while (f<r)
{
t=queue[f++];
printf("%c",t->data);
if (t->lchild)
queue[r++]=t->lchild;
if (t->rchild)
queue[r++]=t->rchild;
}
}
}
- lab7_03_ans.c
/*
編寫函式bintree prelist(bintree t),bintree postfirst(bintree t),
分別返回二叉樹t在前序遍歷下的最後一個結點地址和後序遍歷下的第一個結點地址。
*/
#include "bintree.h"
char *a="ABC##D##EF#G###"; /*擴充二叉樹序樹t的前序序列*/
bintree prelast(bintree t) //遞迴實現
{
if (!t)
return t; //空樹
else
if (t->lchild==NULL &&t->rchild==NULL) //樹根是唯一的結點
return t;
else
if (t->rchild) //右子樹非空
return prelast(t->rchild);
else
return prelast(t->lchild);
}
bintree prelast1(bintree t) //非遞迴實現
{
bintree p=t;
if (p)
{
while (p->lchild || p->rchild ) //p為非葉子
if (p->rchild)
p=p->rchild;
else
p=p->lchild;
}
return p;
}
bintree postfirst(bintree t)
{ bintree p=t;
if (p)
{
while (p->lchild || p->rchild )
if (p->lchild)
p=p->lchild;
else
p=p->rchild;
}
return p;
}
- lab7_04_ans.c
/*
假設二叉樹採用鏈式方式儲存,t為其根結點,編寫一個函式int Depth(bintree t, char x),求值為x的結點在二叉樹中的層次。
*/
#include "bintree.h"
char *a="ABC##D##EF#G###"; /*擴充二叉樹序樹t的前序序列*/
/*
函式Depth,功能:求結點x所在的層次
*/
int Depth(bintree t,char x)
{
int m,n;
if( !t ) return -1; /*未找到的分支標記為-1*/
if( t->data == x ) return 1; /*找到返回1*/
m = Depth(t->lchild,x); /*因為沒有子樹就返回-1,所以沒必要考慮是否存在子樹*/
if( m != -1 ) return m+1; /*找到則加1往上計數*/
else
{ n = Depth(t->rchild,x);
if( n != -1 ) return n+1;
else return -1; /*沒找到繼續返回-1*/
}
}
- lab7_05_ans.c
/*
試編寫一個函式,將一棵給定二叉樹中所有結點的左、右子女互換。
*/
#include "bintree.h"
char *a="ABC##D##EF#G###"; /*擴充二叉樹序樹t的前序序列*/
/*請將本函式補充完整,並進行測試*/
void change(bintree t)
{
bintree temp; /*將t的左右結點交換*/
if (t)
{
temp = t->lchild;
t->lchild = t->rchild;
t->rchild = temp;
if( t->lchild ) change( t->lchild ); /*交換左子樹*/
if( t->rchild ) change( t->rchild ); /*交換右子樹*/
}
}
- lab7_06_ans.c
/*
試編寫一個遞迴函式bintree buildBintree(char *pre, char *mid, int length),
根據二叉樹的前序序列pre、中序序列mid和前序序列長度length,構造二叉樹的二叉連結串列儲存結構,
函式返回二叉樹的樹根地址。
*/
#include "bintree.h"
#include <string.h>
char *a="";
/*
大概的原理:前序序列的第一個字元是樹的根結點root(比如說是 A ),
並且A後面的是左子樹的前序序列,然後右子樹的前序序列
在中序序列中, A 左邊的是左子樹的中序序列, A 右邊是右子樹的中序序列
*/
bintree buildBintree(char *pre, char *mid,int length)
{
if( length )
{
/*↓↓以下兩行,建立樹的根節點*/
bintree root = (bintree)malloc(sizeof(binnode));
root->data = pre[0];
/*↓↓以下三行,將中序序列拆分成【左子樹的中序序列】和【右子樹的中序序列】*/
int i;
for(i=0;mid[i] != pre[0];i++) ;
mid[i] = '\0';
/*↓↓以下兩行,遞迴建立左子樹和右子樹,同理,將前序序列拆分成【左子樹的前序序列】和【右子樹的前序序列】*/
root->lchild = buildBintree(pre+1,mid,i);
root->rchild = buildBintree(pre+i+1,mid+i+1,length-i-1);
/*最後return根結點*/
return root;
}
else return NULL;
}
實驗8-圖
- lab8_01_ans.c
/*
編寫程式輸出以鄰接表為儲存結構的無向圖的各頂點的度。
*/
/**********************************/
/*檔名稱:lab8_01.c */
/**********************************/
#include "ljb.h"
/* 輸出以鄰接表為儲存結構的無向圖g的各頂點的度 */
void degree(LinkedGraph g)
{
EdgeNode *p;
int count;
int i;
for (i=0;i<g.n;i++)
{
count=0;
p=g.adjlist[i].FirstEdge;
while (p)
{
count++;
p=p->next;
}
printf("D(%d)=%d\n",i,count);
}
}
- lab8_02_ans.c
/*
圖採用鄰接表儲存結構,程式設計對圖進行廣度優先遍歷。
*/
/**********************************/
/*檔名稱:lab8_02.c */
/**********************************/
#include "ljb.h"
int visited[M]; /*全域性標誌向量*/
/*請將本函式補充完整,並進行測試*/
void bfs(LinkedGraph g, int i)
{ /*從頂點i出發廣度優先變數圖g的連通分量*/
int queue[M],front,rear,v;
EdgeNode *p;
front=rear=0;
queue[rear++]=i;
visited[i]=1;
while (front<rear)
{
v=queue[front++];
printf("%c ", g.adjlist[v].vertex);
p=g.adjlist[v].FirstEdge;
while (p)
{
if (visited[p->adjvex]==0)
{
queue[rear++]=p->adjvex;
visited[p->adjvex]=1;
}
p=p->next;
}
}
}
/*函式功能:廣度優先遍歷圖g
函式引數:鄰接表g
*/
int BfsTraverse(LinkedGraph g)
{ int i,count=0;
for (i=0;i<g.n;i++)
visited[i]=0; /*初始化標誌陣列*/
for (i=0;i<g.n;i++)
if (!visited[i]) /*vi未訪問過*/
{printf("\n");
count++; /*連通分量個數加1*/
bfs(g,i);
}
return count;
}
- lab8_03_ans.c
/*
圖採用鄰接表儲存結構,程式設計對圖進行深度優先遍歷。
*/
#include "ljb.h"
int visited[M];
/*請將本函式補充完整,並進行測試*/
void dfs(LinkedGraph g,int i)
{ /*從頂點i開始深度優先遍歷圖的連通分量*/
EdgeNode *p;
printf("visit vertex: %c \n",g.adjlist[i].vertex);/*訪問頂點i*/
visited[i]=1;
p=g.adjlist[i].FirstEdge;
while (p) /*從p的鄰接點出發進行深度優先搜尋*/
{
if (visited[p->adjvex]==0)
dfs(g,p->adjvex);
p=p->next;
}
}
/*函式功能:深度優先遍歷圖
函式引數:圖的鄰接表g
*/
void DfsTraverse(LinkedGraph g)
{ int i;
for (i=0;i<g.n;i++)
visited[i]=0; /*初始化標誌陣列*/
for (i=0;i<g.n;i++)
if (!visited[i]) /*vi未訪問過*/
dfs(g,i);
}
- lab8_05_ans.c
/***************************************************/
/* Dijkstra單源最短路徑演算法 */
/***************************************************/
#include "ljjz.h" /*引入鄰接矩陣建立程式*/
typedef enum{FALSE,TRUE} boolean;/*false為0,true為1*/
typedef int dist[M]; /* 距離向量型別*/
typedef int path[M]; /* 路徑型別*/
/*函式功能:Dijkstra演算法求解單源最短路徑
函式引數:圖的鄰接矩陣g;源點v0;路徑向量p;距離向量d
*/
void dijkstra(Mgraph g,int v0,path p,dist d)
{ boolean final[M]; /*表示當前元素是否已求出最短路徑*/
int i,k,j,v,min,x;
/* 第1步 初始化集合S與距離向量d */
for (v=0;v<g.n;v++)
{
final[v]=FALSE;
d[v]=g.edges[v0][v];
if (d[v]<FINITY &&d[v]!=0)
p[v]=v0; else p[v]=-1;
}
final[v0]=TRUE;
d[v0]=0;
/* 第2步 依次找出n-1個結點加入S中 */
for (i=1;i<g.n;i++)
{
min=FINITY;
for (k=0;k<g.n;k++)
if (!final[k] && d[k]<min)
{
v=k;
min=d[k];
}
if (min==FINITY) return ;
final[v]=TRUE;
/*第3步 修改S與V-S中各結點的距離*/
for (k=0;k<g.n;++k)
if (!final[k] && (min+g.edges[v][k]<d[k]))
{
d[k]=min+g.edges[v][k];
p[k]=v;
}
}
}
/*函式功能:輸出有向圖的最短路徑
函式引數:鄰接矩陣g;路徑向量p;距離向量d
*/
void print_gpd(Mgraph g,path p,dist d)
{
int st[M],i,pre,top=-1;
for (i=0;i<g.n;i++)
{ printf("\nDistancd: %7d , path:" ,d[i]);
st[++top]=i;
pre=p[i];
while (pre!=-1) /*從第i個頂點開始向前搜尋最短路徑上的頂點*/
{ st[++top]=pre;
pre=p[pre];
}
while (top>0)
printf("%2d",st[top--]);
}
}
/*---------- 主程式 ------------*/
實驗9-檢索
- lab9_01_ans.c
/* 利用readData()函式從data1.txt中讀入不同規模的資料存入陣列,
編寫基於陣列的順序查詢演算法,測試資料量為1萬、5萬、10萬、20萬、
30萬、40萬和50萬時的資料查詢時間。
*/
#include "ArrayIo.h"
#define N 10000 /*資料量*/
/*請將本函式補充完整,並進行測試*/
int seqsearch(int a[],int n,int key)
{
int i=n-1;
while (i>=0 &&a[i]!=key)
i--;
return i;
}
- lab9_02_ans.c
/* 利用creatLink()函式從data1.txt中讀入不同規模的資料存入不帶頭結點的單鏈表,
編寫基於單鏈表的順序查詢演算法,測試資料量為1萬、5萬、10萬、20萬、
30萬、40萬和50萬時的資料查詢時間。
*/
#include "slnklist.h"
#define N 100 /*資料量*/
/*請將本函式補充完整,並進行測試*/
linklist seqsearch(linklist head, int key)
{
linklist p=head->next;
while (p && p->info!=key)
p=p->next;
return p;
}
- lab9_03_ans.c
/* 利用readData()函式從data2.txt中讀入不同規模的有序資料存入陣列,
編寫基於陣列的二分查詢演算法,測試資料量為1萬、5萬、10萬、20萬、30萬、
40萬和50萬時的資料查詢時間。
*/
#include "ArrayIo.h"
#define N 10000 /*資料量*/
/*請將本函式補充完整,並進行測試*/
int binSearch(int a[],int n,int key)
{
int left,right,mid;
left=0;
right=n-1;
while (left<=right)
{
mid=(left+right)/2;
if (a[mid]==key)
return mid;
else
if (key<a[mid])
right=mid-1;
else
left=mid+1;
}
return -1;
}
- lab9_04_ans.c
/* 利用readData()函式從data2.txt中讀入不同規模的有序資料存入陣列,
編寫基於陣列的二分查詢遞迴演算法。
*/
#include "ArrayIo.h"
#define N 10000 /*資料量*/
/*請將本函式補充完整,並進行測試*/
int binSearch(int a[],int low,int high,int key)
{ int mid;
if (low>high) return -1;
else
{
mid=(low+high)/2;
if (a[mid]==key) return mid;
else
if (key<a[mid])
return binSearch(a,low,mid-1,key);
else
return binSearch(a,mid+1,high,key);
}
}
實驗10-排序
- lab10_01_ans.c
/*
請設計直接插入排序演算法函式void insertSort(int a[],int n),對a[1]..a[n]進行升序排序。
並測試在不同資料規模下的排序效率。
*/
#include "Arrayio.h"
#define N 500000 /*N為資料量大小,因data1.txt中只有50萬個數,所以自行設定N值時需讓N<=500000*/
/*請將本函式補充完整,並進行測試*/
void insertSort(int a[],int n)
{ /*直接插入排序*/
int i,j;
for (i=2;i<=n;i++)
{
//每一趟將a[i]插入到a[1]..a[i-1]
a[0]=a[i];
j=i-1;
while ( a[j] > a[0])
{
a[j+1]=a[j];
j--;
}
a[j+1]=a[0];
}
}
- lab10_02_ans.c
/*
請設計二分插入排序演算法函式void binInsertSort(int a[],int n),對a[1]..a[n]進行升序排序。
並測試在不同資料規模下的排序效率。
*/
#include "Arrayio.h"
#define N 50000 /*N為資料量大小,因data1.txt中只有50萬個數,所以自行設定N值時需讓N<=500000*/
/*請將本函式補充完整,並進行測試*/
void binInsertSort(int a[],int n)
{
int mid,left,right,i,j;
for (i=2;i<=n;i++)
{
left=1;
right=i-1;
while (left<=right)
{
mid=(left+right)/2;
if (a[i]<a[mid])
right=mid-1;
else
left=mid+1;
}
//插入的位置是left
a[0]=a[i];
for (j=i-1;j>=left;j--)
a[j+1]=a[j];
a[left]=a[0];
}
}
- lab10_03_ans.c
/*
請設計shell排序演算法函式void shellSort(int a[],int n),對a[1]..a[n]進行升序排序。
並測試在不同資料規模下的排序效率。
*/
#include "Arrayio.h"
#define N 500000 /*N為資料量大小,因data1.txt中只有50萬個數,所以自行設定N值時需讓N<=500000*/
/*請將本函式補充完整,並進行測試*/
void shellSort(int a[],int n)
{
int i,j,d;
d=n/2;
while (d>=1)
{
for (i=d+1;i<=n;i++)
{
//每一趟將a[i]插入到a[1]..a[i-1]
a[0]=a[i];
j=i-d;
while ( j>=1 &&a[j] > a[0])
{
a[j+d]=a[j];
j=j-d;
}
a[j+d]=a[0];
}
d=d/2;
}
}
- lab10_04_ans.c
/*
請設計簡單選擇排序演算法函式void selectSort(int a[],int n),對a[1]..a[n]進行升序排序。
並測試在不同資料規模下的排序效率。
*/
#include "Arrayio.h"
#define N 50 /*N為資料量大小,因data1.txt中只有50萬個數,所以自行設定N值時需讓N<=500000*/
/*請將本函式補充完整,並進行測試*/
void selectSort(int a[],int n)
{
int i,j,max;
for (i=1;i<n;i++)
{
max=i;
for (j=i+1;j<=n;j++)
if (a[j]>a[max])
max=j;
if (max!=i)
{
a[0]=a[i];
a[i]=a[max];
a[max]=a[0];
}
}
}
- lab10_05_ans.c
/*
請設計篩選函式void sift(int a[],int k,int n),對a[k] 進行篩選,
並利用其設計堆排序演算法函式void heapSort(int a[],int n),
對a[1]..a[n]進行升序排序。並測試在不同資料規模下的排序效率。(詳見lab10_05.c)
*/
#include "Arrayio.h"
#define N 500 /*N為資料量大小,因data1.txt中只有50萬個數,所以自行設定N值時需讓N<=500000*/
/*請將本函式補充完整,並進行測試*/
void sift(int a[],int k,int n)
{
int i,j,finished;
i=k;
j=2*i;
a[0]=a[k];
finished=0;
while((j<=n)&&(!finished))
{
if((j<n)&&(a[j+1]>a[j]))
j++;
if(a[0]>=a[j])
finished=1;
else
{
a[i]=a[j];
i=j;
j=2*j;
}
}
a[i]=a[0];
}
void heapSort(int a[],int n)
{
int i;
for (i=n/2;i>=1;i--)
sift(a,i,n);
for (i=n;i>1;i--)
{
a[0]=a[i];
a[i]=a[1];
a[1]=a[0];
sift(a,1,i-1);
}
}
- lab10_06_ans.c
/*
請設計氣泡排序演算法函式void bubbleSort(int a[],int n),對a[1]..a[n]進行升序排序。
並測試在不同資料規模下的排序效率。
*/
#include "Arrayio.h"
#define N 50 /*N為資料量大小,因data1.txt中只有50萬個數,所以自行設定N值時需讓N<=500000*/
/*請將本函式補充完整,並進行測試*/
void bubbleSort(int a[],int n)
{
int i;
int flag=1;
while (n>1 && flag==1)
{ flag=0;
for (i=1;i<n;i++)
{ if (a[i]>a[i+1])
{ a[0]=a[i];
a[i]=a[i+1];
a[i+1]=a[0];
flag=1;
}
}
n--;
}
}
- lab10_07_ans.c
/*
請設計快速排序演算法函式void quickSort(int a[],int low,int high),對a[low]..a[high]進行升序排序。
並測試在不同資料規模下的排序效率。
*/
#include "Arrayio.h"
#define N 500000 /*N為資料量大小,因data1.txt中只有50萬個數,所以自行設定N值時需讓N<=500000*/
/*請將本函式補充完整,並進行測試*/
void quickSort(int a[],int low,int high )
{
int left,right;
if (low<high)
{
left=low;
right=high;
a[0]=a[low];
do
{//來加比較法的一次劃分
while (left<right && a[right]>a[0])
right--;
if (left<right)
a[left++]=a[right];
while (left<right &&a[left]<=a[0])
left++;
if (left<right)
a[right--]=a[left];
}while (left!=right);
a[left]=a[0];
quickSort(a,low,left-1);
quickSort(a,left+1,high);
}
}
- lab10_08_ans.c
/*
請設計歸併排序演算法函式void mergeSort(int a[],int n),對a[1]..a[n]進行升序排序。
並測試在不同資料規模下的排序效率。
*/
#include "Arrayio.h"
#define N 100000 /*N為資料量大小,因data1.txt中只有50萬個數,所以自行設定N值時需讓N<=500000*/
/*請將本函式補充完整,並進行測試*/
void merge(int a[],int u,int m,int v)
{ /*將有序段a[u..m],a[m+1..v]歸併到a[u..v]*/
int i,j,k,t;
int b[N+1];
i=u; j=m+1; k=u;
while (i<=m && j<=v)
{ if (a[i]<=a[j] )
{ b[k]=a[i];
i++;
}
else
{ b[k]=a[j];
j++;
}
k++;
}
while (i<=m)
b[k++]=a[i++];
while (j<=v)
b[k++]=a[j++];
/*將l2表中的內容拷貝回表l1*/
for (i=u;i<=v;i++)
a[i]=b[i];
}
/*----一趟歸併------*/
int mergepass(int a[],int n,int len)
{ /*對a[1..n]進行長度為len的一趟並歸*/
int i;
i=1;
while (i<=n-2*len+1)
{ merge(a,i,i+len-1,i+2*len-1);
i=i+2*len;
}
if (i+len-1<n)
merge(a,i,i+len-1,n);
}
/*----歸併排序------*/
void mergeSort(int a[],int n)
{ int len;
len=1;
while (len<n)
{ mergepass(a,n,len);
len=len*2;
}
}
/*歸併排序的遞迴實現*/
void mergeSortdc(int a[],int low,int high)
{
int mid;
if (low<high)
{
mid=(low+high)/2;
mergeSortdc(a,low,mid);
mergeSortdc(a,mid+1,high);
merge(a,low,mid,high);
}
}
- lab10_09_ans.c
/*
請設計基於連結串列的基數排序函式void radixSort(linklist head),對帶頭結點的整型非負單鏈表進行升序排序。
並測試在不同資料規模下的排序效率。(注:連結串列中的最大整數為500000)
*/
#include "slnklist.h"
#define N 500000 /*N為資料量大小,因data1.txt中只有50萬個數,所以自行設定N值時需讓N<=500000*/
struct node2
{
linklist front,rear;
};
/*請將本函式補充完整,並進行測試*/
void radixSort(linklist head)
{
struct node2 q[10];/*佇列*/
linklist p,r;
int i,j,k,x;
for (j=0;j<10;j++)
q[j].rear=q[j].front=NULL;
for (i=0;i<6;i++) //排序的最大數為6位數,共進行6趟分配收集過程
{
p=head->next; //分配
while (p)
{
head->next=p->next;
x=p->info;
for (j=0;j<i;j++)
x=x/10;
k=x%10; //取出本次按位分配的值
if (q[k].front==NULL) //佇列為空
{
q[k].front=q[k].rear=p;
}
else //佇列不為空
{
q[k].rear->next=p;
q[k].rear=p;
}
p=head->next;
}
//收集
r=head; //r為鏈尾指標
for (j=0;j<10;j++)
{
if (q[j].front!=NULL)
{ r->next=q[j].front;
r=q[j].rear;
q[j].front=q[j].rear=NULL;
}
}
r->next=NULL;
}
}