1. 程式人生 > >《資料結構與演算法》第一次實驗內容•線性表的建立、銷燬、插入、刪除、遍歷等操作的實現

《資料結構與演算法》第一次實驗內容•線性表的建立、銷燬、插入、刪除、遍歷等操作的實現

《資料結構與演算法》第一次課內容安排

線性表的建立、銷燬、插入、刪除、遍歷等操作的實現

實驗目的:

1、通過實驗掌握、複習C++有關基本知識;

2、通過實驗熟練掌握在連結串列結構中實現線性表操作的方法,並實現基本操作:查詢、插入和刪除等演算法。

實驗內容:

一、連結串列概述:

連結串列是一種動態資料結構,特點是用一組任意的儲存單元(可以是連續的,也可以是不連續的)存放資料元素。連結串列中每一個元素稱為“結點”,每一個結點都是由資料域和指標域組成的,每個結點中的指標域指向下一個結點。Head是“頭指標”,表示連結串列的開始,用來指向第一個結點,而最後一個指標的指標域為NULL(空地址),表示連結串列的結束。可以看出連結串列結構必須利用指標才能實現,即一個結點中必須包含一個指標變數,用來存放下一個結點的地址。

二、實驗步驟(參考)

()、結點的定義

連結串列中的結點中只有一個指標的連結串列稱為單鏈表,這是最簡單的連結串列結構。可定義單鏈表結構的最簡單形式如下。

struct Node

{

int Data;

Node*next;//指標域,指向下一個結

};

這裡用到了結構體型別。其中,*next是指標域,用來指向該結點的下一個結點;Data是一個整形變數,用來存放結點中的資料。當然,Data可以是任何資料型別,包括結構體型別或類型別。

(二)、類的定義

class list

{

 Node*head;

public:

 list(){head=NULL;}

 void insertlist(int aData,int bData);

 void deletelist(int aData);

 void outputlist();

 Node*gethead(){return head;}

};

1.void outputlist();//連結串列結點的訪問輸出

     由於連結串列中的各個結點是由指標連結在一起的,其儲存單元是連續的,因此,對其中任意結點的地址無法向陣列一樣,用一個簡單的公式計算出來,進行隨機訪問。只能從連結串列的頭指標(即head)開始,用一個指標p先指向第一個結點,然後根據結點p找到下一個結點。以此類推,直至找到所要訪問的結點或到最後一個結點(指標為空)為止。

2.void insertlist(int aData,int bData);//表結點的插入

如果要在連結串列中的結點a之前插入結點b,則需要考慮下面幾點情況:

(1) 插入前連結串列是一個空表,這時插入新結點b後。

(2) 若a是連結串列的第一個結點,則插入後,結點b為第一個結點。

(3) 若連結串列中存在a,且不是第一個結點,則首先要找出a的上一個結點,然後使上一個節點的指標域指向b,在令b的指標域指向a,即可完成插入

(4) 如連結串列中不存在a,則插在最後。先找到連結串列的最後一個結點,然後使的指標域指向結點b,而b指標的指標為空。

3. void deletelist(int aData);//表結點的刪除

如果要在連結串列中刪除結點a並釋放被刪除的結點所佔的儲存空間,則需要考慮下列幾種情況:

(1) 若要刪除的結點a是第一個結點,則把head指向a的下一個結點。

(2) 若要刪除的結點a存在於連結串列中,但不是第一個結點,則應使a的上一個結點的指標域指向a的下一個結點。

(3) 空表或要刪除的結點a不存在,則不做任何改變。

(三)、完成程式

下面的程式是本實驗的程式原始碼.

#include"iostream"
using namespace std;
struct Node
{
	int Data;
	Node*next;
};
class list
{
	Node*head;
public:
	list() { head = NULL; }
	void insertlist(int aData, int bData);
	void deletelist(int aData);
	void outputlist();
	Node*gethead() { return head; }
};
void list::insertlist(int aData, int bData)  //設aData是結點a中的資料,bData是結點b中的資料,在a結點的前面插入b結點。
{
	Node*p, *s;        //p指向結點a,s指向結點b
	s = (Node*)new(Node);  //動態分配一個新結點
	s->Data = bData;   //設b為此結點
	p = head;//p是一開始的頭結點
	if (head == NULL)//(1)插入前連結串列是一個空表,這時插入新結點b後。
	{
		head = s;//頭結點為空,就讓頭結點指向b,結點b的指標域賦值空 
		s->next = NULL;
	}
	else
		if (head->Data == aData)//(2) 若a是連結串列的第一個結點,則插入後,結點b為第一個結點。
		{
			s->next = p;
			head = s;
		}
		else
		{
			while (p->next != NULL)//(3) 若連結串列中存在a,且不是第一個結點,則首先要找出a的上一個結點,然後使上一個節點的指標域指向b,在令b的指標域指向a,即可完成插入
			{
				if (p->next->Data == aData)
				{
					s->next = p->next;
					p->next = s;
					break;
				}
				p = p->next;
			}
			if (p->next == NULL)//(4) 如連結串列中不存在a,則插在最後。先找到連結串列的最後一個結點,然後使的指標域指向結點b,而b指標的指標為空。
			{
				p->next = s;
				s->next = NULL;
			}
		}
}
void list::deletelist(int aData)  //設aData是要刪除的結點a中的資料成員
{
	Node*p;            //p用於指向結點a
	p = head;
	if (head->Data == aData)
		head = head->next;
	else
		while (p->next != NULL)
		{
			if (p->next->Data == aData)//迴圈找到這個結點,然後斷開鏈子,把兩頭連上,即可完成刪除中間的那個結點
			{
				p->next = p->next->next;
				break;
			}
			p = p->next;
		}
}
void list::outputlist() //輸出連結串列
{
	Node *p;
	p = head;
	if (head != NULL)
	{
		cout << "新連結串列為:"<<head->Data;
		while (p->next != NULL)
		{
			cout << p->next->Data;
			p = p->next;
		}
	}
}

void main()
{
	list L;
	char option;
	while (1)
	{
		cout << "\n連結串列操作練習:" << endl;
		cout << "1: 建立連結串列" << endl;
		cout << "2: 插入新節點" << endl;
		cout << "3: 刪除節點" << endl;
		cout << "4: 遍歷節點" << endl;
		cout << "0: 退出" << endl;
		cout << "\n請輸入你的選擇:";
		cin >> option;
		switch (option)
		{
		case'0':
			exit(0);
			break;
		case'1':


			break;
		case'2':
			int a, b;
			cout << "請輸入要插入的位置的結點值(在其前面插入):" << endl;
			cin >> a;
			cout << "請輸入要插入的結點的值:" << endl;
			cin >> b;
			L.insertlist(a, b);
			L.outputlist();
			break;
		case'3':
			cout << "輸入要刪除的結點" << endl;
			cin >> a;
			L.deletelist(a);
			L.outputlist();
			break;
		case '4':
			L.outputlist();
			break;
		}
	}
}

有問題請聯絡我 QQ:1239825268

備註:CSDN