严蔚敏版数据结构设计性实验项目 下载本文

中的\一趟归并\算法。 四、实验重点、难点

1、设置一个监视哨。 2、mid的变化。 3、快速排序

4、二路归并中的\一趟归并\算法 五、操作要点

(一)顺序表的顺序查找

#include

#define KEYTYPE int #define MAXSIZE 100 typedef struct { KEYTYPE key; }SSELEMENT;

typedef struct

{ SSELEMENT r[MAXSIZE]; int len; }SSTABLE;

int seq_search(KEYTYPE k, SSTABLE *st) {/*顺序表上查找元素*/ int j;

j = st->len; /*顺序表元素个数*/

st->r[0].key = k; /*st->r[0]单元作为监视哨*/ while(st->r[j].key != k) j--; /*顺序表从后向前查找*/

return j; /*j=0, 找不到;j<>0 找到*/ }

main( )

{ SSTABLE a; int i, j, k;

printf(\请输入顺序表元素(整型量),用空格分开,-99为结束标志 :\j = 0; k = 1; i = 0; scanf(\while (i != -99)

{ j++; a.r[k].key = i; k++; scanf(\输入顺序表元素*/ a.len = j;

printf(\顺序表元素列表显示 :\for (i = 1; i<=a.len; i++) printf(\printf(\

printf(\输入待查元素关键字 : \scanf(\

k = seq_search(i, &a);

if (k == 0) printf(\表中待查元素不存在\\n\\n\

else printf(\表中待查元素存在,为第%d个元素\\n\,k ); }

(二)有序顺序表的二分查找的递归算法

#include

#define KEYTYPE int #define MAXSIZE 100 typedef struct { KEYTYPE key; }SSELEMENT;

- 20 -

typedef struct

{ SSELEMENT r[MAXSIZE]; int len; }SSTABLE;

int search_bin(KEYTYPE k, int low, int high) { /*有序表上二分法查找,递归算法*/ int mid; mid = -1;

if(low <= high) /*low 表示当前表中第1个元素所在下标*/ /*high表示当前表中最后一个元素所在下标*/ {

mid = (low +high)/2; /*mid表示当前表中中间一个元素所在下标*/ if(a.r[mid].key < k)

mid = search_bin(k, mid + 1,high); /*二分法递归查找*/

else if(a.r[mid].key > k)

mid = search_bin(k,low,high - 1);

}

return mid; /*mid = -1 查找不成功;mid!=-1 查找成功*/ }

main( )

{ SSTABLE a; int i, j, k;

printf(\请输入有序表元素,元素为整型量(从小到大输入),用空格分开,-99为结束标

志 :\

j = 0; k = 1; i = 0; scanf(\while (i != -99)

{ j++; a.r[k].key = i; k++; scanf(\输入有序表元素*/ a.len = j;

printf(\有序表元素列表显示 :\for (i = 1; i<=a.len; i++) printf(\printf(\

printf(\输入待查元素关键字 : \scanf(\

k = search_bin(i, 1, a.len);

if (k == -1) printf(\表中待查元素不存在\\n\\n\

else printf(\表中待查元素存在,为第%d个元素\\n\,k); }

(三)排序综合练习

#include

#define KEYTYPE int #define MAXSIZE 100

int createList(RECNODE *r) { int j, k;

printf(\输入待排序数据(整数,以空格隔开,0 结束) : \ while(j != 0) { k++; r[k].key = j; scanf(\ return k; }

frontdisplayList(RECNODE *r, int n) {int i;

printf(\排序前 : \

for (i = 0; i < n; i++) printf(\

- 21 -

printf(\}

reardisplayList(RECNODE *r, int n) {int i;

printf(\排序后 : \

for (i = 0; i < n; i++) printf(\ printf(\}

void insertsort(RECNODE *r, int n) {/*直接插入排序*/ int i,j; for(i = 2; i <= n; i++) { r[0] = r[i];

j = i - 1; /*r[0]是监视哨,j表示当前已排好序列的长度*/

while(r[0].key < r[j].key) /*确定插入位置*/ {r[j + 1] = r[j]; j--;} r[j + 1] = r[0]; /*元素插入*/ } }

void bublesort(RECNODE *r, int n) {/*简单交换排序:冒泡排序*/ int i, j; RECNODE temp; for(i = 1; i < n; i++) for(j = n - 1; j >= i; j--) if(r[j + 1].key < r[j].key) {temp = r[j + 1]; r[j + 1] = r[j]; r[j] = temp;} }

int partition(RECNODE *r, int *low, int *high)

{/*一趟快速排序,返回i,产生了两个独立的待排子序列*/ int i, j; RECNODE temp; i = *low; j = *high; temp = r[i]; /*枢轴记录保存在temp变量中*/ do

{ while((r[j].key >= temp.key) && (i < j))

j--; /*j指针记录和枢轴记录比较*/

if(i < j) { r[i] = r[j]; i++;} while((r[i].key <= temp.key) && (i < j))

i++; /*i指针记录和枢轴记录比较*/

if(i < j) { r[j] = r[i]; j--;} } while(i != j); r[i] = temp; /*枢轴记录的排序位置确定在i*/ return i; }

void quicksort(RECNODE *r, int start, int end) {/*快速排序*/ int i; if(start < end) { i = partition(r, &start, &end);

/*一趟快速排序,返回i,产生了两个独立的待排子序列*/

quicksort(r, start, i - 1);

/*对两个独立的待排子序列分别递归调用快速排序算法*/

quicksort(r, i + 1,end);}

- 22 -

}

void selesort(RECNODE *r, int n) {/*简单选择排序*/ int i,j,k; RECNODE temp; for(i = 1; i < n; i++) { k = i; /*k:最小关键字的初始位置*/ for(j = i + 1; j <= n; j++) if(r[j].key < r[k].key) k = j; /*k:跟踪记录当前最小关键字的位置*/ if(k != i) /*最小关键字元素和待排序列的第一个元素交换*/ {temp = r[i]; r[i] = r[k]; r[k] = temp;} } }

void sift(RECNODE *r, int i, int m)

{/*i是根结点编号,m是以i结点为根的子树中最后一个结点的编号*/ int j; RECNODE temp; temp = r[i]; j = 2 * i; /*j为i根结点的左孩子*/ while(j <= m) {if(j < m && (r[j].key < r[j + 1].key)) j++; /*当i结点有左右孩子时,j取关键字大的孩子结点编号*/ if(temp.key < r[j].key) /*按堆定义调整,并向下一层筛选调整 */ { r[i] = r[j]; i = j; j = 2 * i;} else break; /*筛选调整完成,跳出循环 */ } r[i] = temp; }

void heapsort(RECNODE *r, int n)

{/*堆排序: n为r表中记录数,从r[1]开始放起*/ int i; RECNODE temp; for(i = n/2; i >= 1; i--) sift(r, i, n); /*将无序序列建成大堆*/ for(i = n; i >= 2; i--) {temp = r[1]; /*堆顶及堆尾元素交换*/ r[1] = r[i]; r[i] = temp; sift(r,1,i - 1);

/*交换后,从第一个元素开始调整为大堆,每次记录个数少一个*/

} }

void merge(RECNODE *r, int low, int m, int high)

{ /*两相邻的有序表(一个从low到m;另一个从m+1到high)*/ /*合并为一个有序表(从low到high)*/

RECNODE r1[MAXSIZE]; /*合并时用的缓冲向量*/ int i, j, k; i = low; j = m + 1; k = 0; while(i <= m && j <= high) /*两相邻的有序表合并*/ if(r[i].key <= r[j].key) {r1[k] = r[i]; i++; k++;}

- 23 -