帶頭結點的單鏈表操作說明
阿新 • • 發佈:2017-06-10
內存 arr 位置 not space n) end front tin
一、單鏈表簡介
相對於以數組為代表的“順序表”而言,單鏈表雖然存儲密度比較低(因為數據域才是我們真正需要的,指針域只是用來索引,我們並不真正需要它),但是卻具有靈活分配存儲空間、方便數據元素的刪除、方便元素插入等優點
單鏈表是線性表鏈式存儲的一種,其儲存不連續。單鏈表的數據結構中包含兩個變量:數據和指向下一結點的指針。一個結點只知道下一個結點的地址。一個單鏈表必須有一個頭指針,指向單鏈表中的第一個結點。否則鏈表會在內存中丟失。
一般的鏈表可以不帶頭結點,頭指針直接指向第一個節點,如下圖:
但是這樣的鏈表有一個很大的問題,就是元素插入與刪除操作時,需要考慮是否要改動頭指針,而改動指針如果反應在函數中,那麽形參必須使用二重指針,既加大了編寫程序的難度,而且還降低了可讀性,容易出錯,因此“帶頭結點的單鏈表”使用更方便,也就是頭指針指向的節點不存放數據,只作為鏈表的開始,這樣一來,針對第一個節點的操作和針對其他節點的操作就完全一樣的,十分方便,如圖所示:
二、帶頭結點的單鏈表各種操作
下面我們討論一下帶頭結點的單鏈表的各種操作
1、鏈表數據結構的聲明
1 using namespace std; 2 const int MAXSIZE = 1000; 3 template <class T> 4 struct Node 5 { 6 T data; //數據域 7 Node *next; //指針域 8 };
2、鏈表模板類的聲明
1 template <class T> 2 class LinkList 3 { 4 public: 5 LinkList(){front = newNode<T>;} //the constructor function without arguments 6 LinkList( T a[], int n); //the constructor function initialized by array of n elements 7 ~LinkList(); 8 int GetLength(); //get the length of the LIST 9 void PrintList(); //print the element of the list10 void Insert(int i,T x);// insert element x in the i-th location 11 T Delete(int i); //delete the i-th element and return its value 12 Node<T> *Get(int i); //get the address of i-th element 13 int Locate(T x); //find the element whose value is x and return its index 14 private: 15 Node<T> *front; //head pointer 16 };
3、用頭插法建立新鏈表,也就是每次插入的新節點都在鏈表的頭部,註釋部分給出的是尾插法的實現方式
1 template <class T> 2 LinkList<T>::LinkList(T a[], int n) 3 { 4 // insert element at the first location of the existing link list 5 front = new Node<T>; 6 front->next = NULL; 7 for(int i=n-1; i>=0; i--) 8 { 9 Node<T> *s = new Node<T>; 10 s->data = a[i]; 11 s->next = front->next; 12 front->next = s; 13 } 14 // insert element at the tail of the existing link list 15 16 /* 17 front = new Node<T>; 18 Node<T> *r = front; 19 for(int i=0; i<n; i++) 20 { 21 Node<T> *s = new Node<T>; 22 s->data = a[i]; 23 r->next = s; 24 r=s; 25 } 26 r->next = NULL; 27 */ 28 }
4、打印鏈表
1 template <class T> 2 void LinkList<T>::PrintList() 3 { 4 Node<T> *p = front; 5 if(p->next==NULL) 6 cout<<"link is enpty"<<endl; 7 else 8 { 9 p = p->next; 10 while(p) 11 { 12 cout<<p->data<<" "; 13 p = p->next; 14 } 15 } 16 }
5、插入節點
1 template <class T> 2 void LinkList<T>::Insert(int i,T x) 3 { 4 Node<T> *p = front; 5 if(i!= 1) p=Get(i-1); // if not insert the elelment in the first location 6 if(p) 7 { 8 Node<T> *s = new Node<T>; 9 s->data = x; 10 s->next = p->next; 11 p->next = s; 12 } 13 else 14 cout<<"error!"<<endl; 15 }
6、刪除節點
1 template <class T> 2 T LinkList<T>::Delete(int i) 3 { 4 Node<T> *p = front; 5 if(i!=1) p = Get(i-1); 6 Node<T> *q = p->next; 7 p->next = q->next; 8 T x = q->data; 9 delete q; 10 return x; 11 }
7、按位查找節點,返回第i個節點的地址
1 template <class T> 2 Node<T> *LinkList<T>::Get(int i) 3 { 4 Node<T> *p = front->next; 5 int j=1; 6 while(p&&j!=i) 7 { 8 p = p->next; 9 j++; 10 } 11 return p; 12 }
8、按值查找,返回給定值對應的節點的序號
1 template <class T> 2 int LinkList<T>::Locate(T x) 3 { 4 5 Node<T> *p = front->next; 6 int j=1; 7 while(p) 8 { 9 if(p->data==x) return j; 10 p = p->next; 11 j++; 12 } 13 return -1; //search fail 14 }
9、獲取鏈表長度
1 template <class T> 2 int LinkList<T>::GetLength() 3 { 4 Node<T> *p = front->next; 5 int count=0; 6 while(p) 7 { 8 p = p->next; 9 count++; 10 } 11 return count; //get the length of linklist 12 }
10、析構函數
1 template <class T> 2 LinkList<T>::~LinkList() 3 { 4 Node<T> *p = front; 5 while(p) 6 { 7 front = p; 8 p = p->next; 9 } 10 }
11、主函數(由於使用模板類實現,以上所有代碼建議放入 .h頭文件,主函數則放入.cpp文件 所有代碼在dev c++環境中測試通過)
1 /* 2 線性表相關成員函數的實現 3 */ 4 #include <iostream> 5 #include <cmath> 6 #include <stdlib.h> 7 #include "linked_list.h" 8 using namespace std; 9 int main() 10 { 11 int a[7] = {1,2,3,4,5,6,7}; 12 LinkList <int> list(a,7); 13 list.PrintList(); 14 cout<<endl; 15 cout<<list.Get(3)<<endl; 16 Node<int> temp = *list.Get(3); 17 cout<<temp.data<<endl; 18 //cout<<*(list.Get(3))<<endl; 19 cout<<list.GetLength()<<endl; 20 list.Insert(3,11); 21 cout<<list.GetLength()<<endl; 22 list.PrintList(); 23 cout<<list.Locate(5)<<endl; 24 int x = list.Delete(4); 25 cout<<"刪除元素:"<<x<<endl; 26 list.PrintList(); 27 //int p = list.Locate(1000); 28 //cout<<"元素4的位置:"<<p<<endl; 29 system("pause"); 30 return 0; 31 }
帶頭結點的單鏈表操作說明