這是鏈表的,雖然代碼有點長,但這只是爲了規範化才這樣寫的,每行代碼都有詳細註釋:我認爲這是我見過最簡單的鏈表了,小白完全看的懂,大神勿噴
如果不會的給我留言
第一個是線性表類:List.h
#include"節點類.h"
#ifndef LIST
#define LIST
class List
{
public:
List();//鏈表不需要聲明長度,而是動態在內存中開闢空間
~List();//析構函數,用來回收內存
void ClearList();//清空鏈表,清空存儲了數據的結點
bool ListEmpty();//判斷鏈表是否爲空
bool ListInsert(int i, Node *n);//將節點插入到指定位置
bool getElem(int i,Node *n);//根據位序查找指定元素
bool ListDelete(int i, Node * n);//根據位序刪除指定節點
int LocateElem(Node *n);//根據元素找到對應的序號
void ListTraverse();//遍歷鏈表
bool ListInsertFirst(Node *n);//往首元結點插入數據
bool priorElem(Node *pCurrNode , Node *pPreElem);//查詢指定節點的前驅
bool afterElem(Node *pCurrNode, Node *pPreElem);//查詢指定節點的後繼
Node *list;//節點指針
//不需要長度
int length;//存儲的元素個數
};
#endif // !LIST
第二個頭文件:節點類.h
#ifndef NODE
#define NODE
//節點類
class Node
{
public:
int data;//數據域
Node *next;//指針域,用於指向下一個節點
void printNode();//節點數據輸出
};
#endif // !Node
實現:
#include"節點類.h"
#include"List.h"
#include<iostream>
using namespace std;
void Node::printNode()//將數據輸出
{
cout << data << endl;
}
List::List()
{
//首先創建一個頭結點,然後通過頭結點來操作整個鏈表
list = new Node;//從堆中申請動態內存
list->data = 0;//頭結點的數據域沒有意義
list->next = NULL;//先讓其默認指向空
length = 0;//沒有存儲數據的節點
}
List::~List()
{
//將鏈表中的所有節點包括頭結點釋放
//先清空鏈表
ClearList();
delete list;//將頭結點刪除
list = NULL;//將頭結點清空
}
void List::ClearList()
{
length = 0;//將存儲數據的個數設置爲0
Node *curr = list->next;//將頭結點的指針臨時存儲
while (curr != NULL)//當最後一個節點的指針域不指向空時(也就是不是最後一個節點時)
{
//使用一個臨時變量存儲下一個節點
Node *temp = curr->next;
delete curr;//將當前節點刪除
curr = temp;//將當前節點的下一個節點賦值給當前節點
}
list->next = NULL;//讓頭結點指向爲空
}
bool List:: ListEmpty()//判斷鏈表是否爲空
{
if (list->next == NULL)
{
return true;
}
else
return false;
}
bool List::ListInsert(int i, Node *n)//往鏈表中插入數據
{
//判斷i是否合法
if (i<0 || i>length)
{
return false;
}
//將頭結點作爲當前節點
Node *curr = list;
Node *currBefore = NULL;//前驅節點
for (size_t k = 0; k <= i; k++)//按順序將當前節點往後移動
{
currBefore = curr;//將當前節點往後移動一次,他的前驅指向他原來的位置
curr = curr->next;//將當前節點往後移
}
//創建一個新的節點來插入
Node *newNode = new Node;
//將新創建的節點指向位序爲i的節點
newNode->data = n->data;
newNode->next = curr;
currBefore->next = newNode;
length++;
return true;
}
void List::ListTraverse()//遍歷鏈表(輸出)
{
Node *curr = list;
while (curr->next != NULL)
{
curr = curr->next;
curr->printNode();
}
}
bool List::ListInsertFirst(Node *n)//插入到首元結點
{
Node *newNode = new Node;
newNode->data = n->data;
if (list->next == NULL)
{
list->next = newNode;
}
else
{
Node *temp = list->next;
newNode->next = temp;
list->next = newNode;
}
length++;//長度增加
return true;
}
bool List::getElem(int i, Node *n)//根據位序獲取鏈表中的元素
{
if (i<0 || i>length)
{
return false;
}
//從頭結點往後遍歷
Node *curr = list;
for (size_t k = 0; k <= i; k++)
{
curr = curr->next;
}
n->data = curr->data;
return true;
}
bool List::ListDelete(int i, Node *n)//刪除節點
{
if (i<0 || i>length)
{
return false;
}
Node *curr = list;
Node *currBefore = NULL;
for (size_t k = 0; k <= i; k++)
{
currBefore = curr;
curr = curr->next;
}
n->data = curr->data;
Node *currAfter = curr->next;
//將當前節點刪除
delete curr;
//將當前節點的前驅指向當前節點的後繼
currBefore->next = currAfter;
length--;
return true;
}
bool List::priorElem(Node *pCurrNode, Node *pPreElem)//獲取指定節點的前驅節點
{
Node *temp = new Node;
Node *curr = list;//將頭結點設爲當前節點
while (curr->next != NULL)
{
temp = curr;
curr = curr->next;
if (curr->data == pCurrNode->data)
{
pPreElem->data = temp->data;
cout << "指定節點的前驅節點pPreElem = " << temp->data << endl;
}
}
return true;
}
bool List::afterElem(Node *pCurrNode, Node *pPreElem)//獲取指定節點的後繼節點
{
Node *temp = new Node;
Node *curr = list;
while (curr->next != NULL)
{
temp = curr;
curr = curr->next;
if (temp->data == pCurrNode->data)
{
pPreElem->data = curr->data;
cout << "指定節點的後繼節點afterElem = " << pPreElem->data << endl;
}
}
if (curr->next == NULL)
{
cout << "這個節點沒有後繼節點!" << endl;
return false;
}
return true;
}
int List::LocateElem(Node *n)//查找指定節點的位序
{
int a = 0;
Node *curr = list;
while (curr->next != NULL)
{
a++;
curr = curr->next;
if (curr->data == n->data)
{
cout <<"該節點的位序是:"<< a << endl;
}
}
return a;
}
測試:#include"List.h"
#include<conio.h>
using namespace std;
int main()
{
List *L = new List();
Node n1;
char d = 'ss';
n1.data = 1;
Node n2;
n2.data = 2;
Node n3;
n3.data = 3;
Node n4;
n4.data = 4;
Node n5;
n5.data = 5;
L->ListInsert(0, &n1);
L->ListInsert(1, &n2);
L->ListInsert(2, &n3);
L->ListInsert(3, &n4);
L->ListInsert(4, &n5);
L->ListTraverse();
L->priorElem(&n3, &n1);
L->afterElem(&n5, &n1);
L->LocateElem(&n3);
getch();
}