桂電-數學與計算科學學院-《資料結構實驗-寧黎華編》(實驗一)
實驗一:順序表的基本操作
1、實驗目的
(1) 掌握順序表的基本運算,熟悉對順序表的一些基本操作和具體函式的定義。 (2) 掌握順序儲存的概念,學會定義線性表的順序儲存型別。 (3) 熟悉c語言程式的基本結構,掌握程式中的使用者標頭檔案、實現檔案和主檔案之間的相互關係及各自的作用。 (4) 熟悉c語言環境的使用及程式的輸入、編輯、除錯和執行的全過程。 (5) 加深對順序儲存結構的理解,逐步培養解決實際問題的程式設計能力。
2、實驗要求
(1) 熟練掌握線性表的儲存結構及其基本操作。 (2) 理解所給出的演算法,掌握線性表在實際中的應用。 (3) 將上機程式除錯通過,並能獨立完成一至兩個拓展題目。
3、實驗內容
實現順序表上的插入、刪除等操作。除錯程式並對相應的輸出作出分析;修改輸入資料,預期輸出並驗證輸出的結果。加深對有關演算法的理解。
4、試驗方法
第一步:定義順序表的儲存結構。 第二步:編寫順序表操作的具體函式定義。 第三步:使用定義的順序表並呼叫順序表的一些操作,實現具體運算。 具體函式的定義有: (1) insert(L,i,x)在順序表的第i個元素之前插入一個新元素x. (2) delete (L,i) 刪除順序表的第i個元素。 (3) listprint(L) 輸出順序表。
5、驗證程式
#define MAXSIZE 100 //巨集定義 #include<stdio.h> //函式標頭檔案 typedef int elemtype; //定義順序表的結構 typedef struct //資料表成員所佔儲存空間 { elemtype vec[MAXSIZE]; int last; //順序表中最後一個元素在陣列中的下標,從0開始 }sequenlist; int insert(sequenlist *L,int i,elemtype x)//插入函式 { int j; if(((*L).last)>=MAXSIZE-1) { printf("the list is overflow!\n"); return 0; //溢位判斷 } else if((i<1)||(i>(*L).last+2)) { printf("position is not correct!\n"); return 0; //插入位置不對 } else { for(j=(*L).last;j>=i-1;j--) (*L).vec[j+1]=(*L).vec[j]; (*L).vec [i-1]=x; (*L).last++; } return 1; } void delete(sequenlist *L,int i)//刪除第i個元素 { int j; if((i<1)||(i>(*L).last+1)) printf("delete fail\n"); else { for(j=i;j<=(*L).last;j++) (*L).vec[j-1]=(*L).vec[j]; (*L).last--; } } void listprint(sequenlist *L)//輸出函式 { int i; for(i=0;i<=(*L).last;i++) printf("i,e=%d,%d\n",i,L->vec[i]); } main() //主函式 { sequenlist s1={{1,2,3,4,5,6,7,8,9,10},9};//定義一個變數 sequenlist *L; int i,j,x; L=&s1; printf("please input the insert position and insert value\n"); scanf("%d%d",&i,&x); printf("the insert position :%d\ninsert value :%d\n",i,x); insert(L,i,x); listprint(L); printf("please input the delete position:"); scanf("%d",&j); delete(L,j); listprint(L); }
驗證程式結果如下圖:
6、預習思考題
除錯好上述程式後,試著完成以下拓展內容: (1) 定義一個定位函式locate(L,x),具有元素檢索的功能。當順序表中存在一個值為x的資料元素時,返回第一次找到的資料元素的位序,否則,給出一個值,表示值為x的元素不存在。在主程式中呼叫該函式,分析操作結果。 (2) 定義一個逆置函式diverse(L),把順序表進行逆置。在主程式中呼叫該函式,分析操作結果。 (3) 定義一個函式delsame(L),把順序表中重複的元素刪除掉,只保留一個。在主程式中呼叫該函式,分析操作結果。 思考一:在做思考題1的時候返回值的返回有一定的難度,由於迴圈的作用返回值可能返回不同的結果,導致返回值被覆蓋,不能有效返回。
int locate(sequenlist *L,int x)//定位函式
{
int i,a=-1;
for(i=0;i<=(*L).last;i++)
{if(x==(*L).vec[i]){a=i;break;}}
return a;
}
main() //主函式
{
sequenlist s1={{1,2,3,4,5,6,7,8,9,10},9};//定義一個變數
sequenlist *L;
int i,j,x,k,y;
L=&s1;
printf("please input the insert position and insert value\n");
scanf("%d%d",&i,&x);
printf("the insert position :%d\ninsert value :%d\n",i,x);
insert(L,i,x);
listprint(L);
printf("please input the delete position:");
scanf("%d",&j);
delete(L,j);
listprint(L);
printf("輸入定位數值");
scanf("%d",&k);
y=locate(L,k);
if(y==-1)
printf("查找不出來\n");
else printf("該數值的位置是%d\n",y);
}
程式執行結果如下圖: 思考二:根據前後位置調換直接互換數值,要求是i<j。
void diverse(sequenlist *L)//換序函式
{
int i,j,t;
for(i=0,j=L->last;i<j;i++,j--)
{
t=(*L).vec[i];
(*L).vec[i]=(*L).vec[j];
(*L).vec[j]=t;
}
}
main() //主函式
{
sequenlist s1={{1,2,3,4,5,6,7,8,9,10},9};//定義一個變數
sequenlist *L;
int i,j,x,k,y;
L=&s1;
printf("please input the insert position and insert value\n");
scanf("%d%d",&i,&x);
printf("the insert position :%d\ninsert value :%d\n",i,x);
insert(L,i,x);
listprint(L);
printf("please input the delete position:");
scanf("%d",&j);
delete(L,j);
listprint(L);
printf("輸入定位數值");
scanf("%d",&k);
y=locate(L,k);
if(y==-1)
printf("查找不出來\n");
else printf("該數值的位置是%d\n",y);
printf("調序函式:\n");
diverse(L);
listprint(L);
}
執行結果如下圖: 思考三:先確定第一個值,然後用後面的值進行比較,如果相等直接呼叫刪除函式,不相等進行下一個比較,然後用第二個數值與後面的數值進行比較。最後比計較結束。
void delsame(sequenlist *L)//刪除函式
{
int i,j;
for(i=0;i<L->last;i++)
for(j=i+1;j<=L->last;j++)
if(L->vec[i]==L->vec[j])
delete(L,j+1);
}
main()
{
..........
.........
printf("刪除重複的數值:\n");
delsame(L);
listprint(L);
}
執行結果如下圖: