數據結構-單向鏈表 C和C++的實現
阿新 • • 發佈:2017-07-14
下標 using print find 十分 for null type 一位 。
數據結構,一堆數據的存放方式。
今天我們學習數據結構中的 鏈表:
數組,大家相當熟悉的存放數據方式,而鏈表是數組的一種特殊方式,它每個節點包括兩個部分:
- 數據域:存放數據,此部分與數組相同
- 指針域:存放了下一個節點的地址
鏈表比數組多了指針域,因為鏈表需要通過上一個節點的指針域去找下一個數據,比如有一個鏈表ABCD四個節點,我們要訪問D裏邊的數據。操作如下:
- 先通過A節點的指針域找到B節點
- 再通過B節點的指針域找到C節點
- 再通過C節點的指針域找到D節點
- 獲取D節點數據域的數據
對比數組直接通過下標訪問,鏈表的訪問方式相當麻煩,既然這麽麻煩,為什麽還有鏈表這種數據結構呢?因為鏈表插入刪除節點方式十分便捷,在數據量大的時候,刪除數組的數據需要把刪除數據後面的數據都前移一位,而鏈表只需要改變前一個元素的指針域,插入和刪除操作速度快
這麽厲害的東西,還是看程序比較直接
單向鏈表
C
(此處插入代碼)
C++
在C++中,使用模板的方法實現
本程序包括3個文件組成,他們分別是:
定義節點類:Node.h
這個類定義了每個節點的兩個區域:m_tpData數據域 和 m_tpNext指針域:
#include <iostream> using namespace std; template <typename T> class Node { public: Node(); Node(T data); ~Node(); void setData(T data); T getData();void setNext(Node<T> *next); Node* getNext(); void printData(); private: T *m_tpData; Node<T> *m_tpNext; }; template <typename T> Node<T>::Node() { m_tpData = new T; m_tpNext=NULL; } template <typename T> Node<T>::Node(T data) { m_tpData= new T(data); m_tpNext=NULL; } template <typename T> Node<T>::~Node() { delete m_tpData; m_tpData=NULL; } template <typename T> void Node<T>::setData(T data) { *m_tpData = data; } template <typename T> T Node<T>::getData() { return *m_tpData; } template <typename T> void Node<T>::setNext(Node<T> *next) { m_tpNext = next; } template <typename T> Node<T>* Node<T>::getNext() { return m_tpNext; } template <typename T> void Node<T>::printData() { cout<<*m_tpData<<endl; }
鏈表類 LinkList.h
#include <iostream> #include "Node.h" using namespace std; template <typename T> class LinkList { public: LinkList(); ~LinkList(); bool isListEmpty(); bool clearList(); int getListLength(); int getElemIndex(T &elem); bool getListElem(int index,T* elem); //bool getListPrevious(int index,T* elem); //bool getListNext(int index,T* elem); bool ListInsert(int index,T &elem); bool ListDelete(int index,T *elem); void ListPrint(void); private: Node<T> *m_pList; int m_iLength; }; template <typename T> LinkList<T>::LinkList() { m_pList = new Node<T>; m_pList->setData(NULL); m_pList->setNext(NULL); m_iLength=0; } template <typename T> LinkList<T>::~LinkList() { Node<T> *nextNode = m_pList; while(nextNode->getNext()!=NULL) //delete Node while pointerNext == NULL { nextNode=m_pList->getNext(); delete m_pList; m_pList = nextNode; } delete m_pList;//delete last Node m_pList = NULL; } template <typename T> bool LinkList<T>::isListEmpty() { if(m_iLength==0) return true; return false; } template <typename T> bool LinkList<T>::clearList() { if(isListEmpty()) { cout<<"List empty clear fail"<<endl; return false; } //delete All node except first node Node<T> *nowNode = m_pList->getNext(); Node<T> *nextNode = m_pList->getNext(); while(nextNode->getNext()!=NULL) { nextNode=nowNode->getNext(); delete nowNode; nowNode = nextNode; } delete nowNode;//delete last Node m_iLength = 0; m_pList->setNext(NULL); return true; } template <typename T> int LinkList<T>::getListLength() { return m_iLength; } template <typename T> int LinkList<T>::getElemIndex(T &elem) { Node<T> *tempNode = m_pList; for(int i=0;i<m_iLength;i++) { tempNode = tempNode->getNext(); if(elem == tempNode->getData()) { return i; } } return -1; } template <typename T> bool LinkList<T>::getListElem(int index,T* elem) { if(index<0 || index>= m_iLength) { return false; } Node<T> *tempNode = m_pList; for(int i=0;i<=index;i++) { tempNode=tempNode->getNext(); } *elem = tempNode->getData(); return true; } template <typename T> bool LinkList<T>::ListInsert(int index,T &elem) { //index out of range if(index<0 || index>m_iLength) { return false; } // Node<T> *tempPreNode = m_pList; for(int i=0;i<index;i++) { tempPreNode = tempPreNode->getNext(); } Node<T> *newnode = new Node<T>; //create a new node if(newnode == NULL) { cout<<"new node create fail"<<endl; return false; } Node<T> *tempNode= tempPreNode->getNext();//save pre node pointer tempPreNode->setNext(newnode); //set pre node pointer to new node address newnode->setNext(tempNode);//set new node pointer to pre node pointer newnode->setData(elem); //set new node new data m_iLength++; return true; } template <typename T> bool LinkList<T>::ListDelete(int index,T *elem) { //index out of range if(index<0 || index>=m_iLength) { return false; } // Node<T> *tempPreNode = m_pList; //pre node for(int i=0;i<index;i++)//find pre node { tempPreNode = tempPreNode->getNext(); } Node<T> * tempNode = tempPreNode->getNext();//save delete point pointer tempPreNode->setNext(tempNode->getNext());//set pre node point to next node *elem = tempNode->getData(); delete tempNode; m_iLength--; return true; } template <typename T> void LinkList<T>::ListPrint(void) { if(isListEmpty()) { cout<<"List empty"<<endl; return; } Node<T> *tempNode=m_pList->getNext(); while(tempNode->getNext() != NULL) { tempNode->printData(); tempNode = tempNode->getNext(); } tempNode->printData(); cout<<"end"<<endl; }
單項鏈表模板定義完了,我們在main.cpp中使用int類型實例化它、並測試它的功能
#include <iostream> #include <string> #include "LinkList.h" using namespace std; int main(void) { /*insert data check*/ int data[10]={0,1,2,3,4,5,6,7,8,9}; LinkList<int> *linklist = new LinkList<int>; for(int i=0;i<5;i++) { linklist->ListInsert(i,data[i]); } linklist->ListPrint(); /*getElemIndex check*/ cout<<"getElemIndex:"<<linklist->getElemIndex(data[4])<<endl; /*getListElem check*/ int getdata; linklist->getListElem(2,&getdata); cout<<"getListElem:"<<getdata<<endl; /*delete data check*/ int deletedata; linklist->ListDelete (0,&deletedata); cout<<"delete data:"<<deletedata<<endl; linklist->ListPrint(); /*clearList check*/ linklist->clearList(); linklist->ListPrint(); delete linklist; linklist = NULL; system("pause"); return 0; }
運行結果如下:
數據結構-單向鏈表 C和C++的實現