1. 程式人生 > >桂電-數學與計算科學學院-《資料結構實驗-寧黎華編》(實驗一)

桂電-數學與計算科學學院-《資料結構實驗-寧黎華編》(實驗一)

實驗一:順序表的基本操作

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);
}

執行結果如下圖: 在這裡插入圖片描述