1. 程式人生 > >資料結構回顧-------單鏈表

資料結構回顧-------單鏈表

單鏈表,用指標來實現的線性表

為了方便操作,我們定義一個頭指標來操作連結串列

結構體為Node      一個整型data,一個Node指標next指向下一個節點

封裝類為LinkList    連結串列的各個操作具體看類的函式即可。

/*
 * 單鏈表的實現 
 *為了看起來簡單點,這裡用int型別作為連結串列的資料型別 
*/

#include<iostream>

using namespace std;

//定義一個結構體。data存貯資料,next指標指向下一個資料 
struct Node
{
	int data;
	Node * next;
} ;
 
class LinkList
{
	public:
		
		LinkList()   //無參的建構函式,構造一個空的連結串列 
		{
			first = new Node;
			first->next = NULL; 
		} 
		
		//有參建構函式,我把尾插法和頭插法建立連結串列都放裡面了 
		LinkList(int a[],int n) 
		{
			
			/*
			*	
			//頭插法建立單鏈表 ---我不喜歡用這個,註釋掉 
			
			first = new Node;//初始化指標 
			first->next = NULL;
			for(int i = 0;i < n;i++) 
			{
				Node *s = new Node;
				s->data = a[i];
				
				s->next = first->next;  //節點s的指標域指向頭指標的下一個資料體
				first->next = s;        //頭指標的指標域指向s。   
				//這兩行程式碼實現了將一個節點s插入到頭指標的下一個節點 
			} 
			*/ 
			
			/*
			*尾插法建立單鏈表 
			*/
			first = new Node;//生成頭節點
			Node *r = first;//初始化尾指標
			for(int i = 0;i < n;i++)
			{
				//建立一個節點 
				Node *s = new Node;
				s->data = a[i];
				
				r->next = s; //尾指標的下一個節點指向是s 
				r = s;        //尾指標r移到s節點 
			} 
			r->next = NULL;//單鏈表建立完畢,將終端節點指標域置空 
		 
		} 
	
		//解構函式,釋放資源 
		~LinkList()
		{
			while(first != NULL)
			{
				Node *q = first;//暫存被釋放的節點 
				first = first->next;//first節點往後移 
				delete q;
			}
		}
	
		int Getlength()     //求單表的長度 
		{
			Node *p = first->next;//p指向連結串列第一個非空節點(不是頭結點),操作連結串列 
			int count = 0;
			
			while(p != NULL)
			{
				p = p->next;
				count++;
			} 
			return count;
		} 
	
		int Get(int i )  //按位查詢,在單鏈表中查詢第i個元素
		{
			Node *p = first->next;
			int count = 1;
			while(p != NULL && count < i)
			{
				p = p->next;
				count++;
			} 
			if(p == NULL)
				throw "位置不正確";
			else
				return p->data;
		}
		 
	
		int Locate(int x)  //按值查詢,查詢單鏈表中值為x的元素序號
		{
			Node *p = first->next;
			int count = 1;
			//迴圈遍歷單鏈表,如果找到相等資料,返回count 
			while(p != NULL)
			{
				if(p->data == x)
					return count;
				p = p->next;
				count++;
			}
			//退出迴圈代表查詢失敗,連結串列中沒有這個資料 
			return 0;
		}
	
		void Insert(int i ,int x)  //插入操作,在單鏈表中第i個位置插入值為x的元素
		{
			Node *p = first;//工作指標應該指向頭結點
			int count = 0;
			//迴圈,工作節點p找到第i個節點的位置 
			while(p != NULL && count < i-1)
			{
				p = p->next;
				count++;
			} 
			if(p == NULL)
				throw "位置不正確";
			else
			{
				//建立新節點 
				Node *s = new Node;
				s->data = x;
				//將節點s插入到節點p之後 
				s->next = p->next;
				p->next = s;
			}
		} 
	
		int Delete(int i)   //刪除操作,刪除表中的第i個元素
		{
			Node *p = first;
			int count = 0;
			//工作指標找到i的前一個節點位置 
			while(p != NULL && count < i-1)
			{
				p = p->next;
				count++;
			}
			if(p == NULL || p->next == NULL) //如果節點p不存在或者p的後繼節點不存在
				throw "位置不正確";
			else
			{
				Node *q = p->next; //暫存被刪除節點 
				int x = q->data;
				p->next = q->next;//將第i個節點從連結串列中摘除
				delete q;
				return x; 
			} 
		}
	
		void PrintList()        //遍歷操作,按序號輸入出各個元素
		{
			Node *p = first->next;
			while(p != NULL)
			{
				cout<<p->data<<" ";
				p = p->next;
			}
			cout<<endl;
		}
	
	private:
		Node *first; //頭指標 
		 
} ;

int main()
{
	int a[10] = {1,2,3,4,5,6,7,8,9,0};
	int n = 10;
	LinkList ll(a,n);
	
	cout<<"第5個數據是:"<<ll.Get(5)<<endl;
	cout<<"連結串列的長度時:"<<ll.Getlength()<<endl;
	cout<<"值為6的資料所在的位置是:"<<ll.Locate(6)<<endl;
	cout<<"遍歷插入前的連結串列:";
	ll.PrintList();
	cout<<"往第7個位置插入資料12";
	ll.Insert(7,12);
	cout<<"遍歷插入後的連結串列:";
	ll.PrintList();
	cout<<"刪除第三個資料後的連結串列:";
	ll.Delete(3); 
	ll.PrintList(); 
	
	return 0;


測試結果:


還可以通過控制檯資料資料,然後將使用者手動輸入的資料存放在連結串列中,這個實現起來應該不難,稍微修改一下程式碼就可以啦