靜態鏈表,也是線性表的一種表現形式之一,本篇文章中僅僅簡單展示如何簡單實現其基本功能及簡單的測試調試。
靜態鏈表:利用結構體數組模擬單鏈表,其中,結構體中的next爲int型,指向數組的某一個下標,從而實現模擬單鏈表
特點:設置空閒鏈(模擬單鏈表從內存中申請空間)使得未被使用的數組下標可以被尋址,寫入新數據,有數據釋放時,空間歸還到空閒鏈。
亮點:相對於順序表來說,插入和刪除時無需移動大量元素
缺點 :同樣沒有解決跟順序表一樣的可拓展性不強的特點(不確定表長時容易不知何時會表滿,溢出)
上代碼:
結構體實現:
#pragma once
#include<iostream>
using namespace std;
const int MaxSize = 100; //自定義表長
template<typename T>
class Node {
public:
T data;
int next; //存儲指向下一個節點的數組的下標
};
//單鏈表類模板的實現:
#pragma once
#include"Node.h"
template<typename T>
class staticLink {
public:
staticLink(T a[],int n);
~staticLink();
int Length(); //返回單鏈表的長度
T Get(int i); //按位查找,查找第i個節點的元素
int Locate(T x); //按值查找,查找鏈表中第一個值爲x的元素,並返回序號
bool Insert(int i, T x); //插入元素,在第i個位置插入值x
bool Delete(int i); //刪除節點,刪除第i個節點
bool InsertHead(T x); //頭插法插入節點
bool InsertTail(T x); //尾插法插入節點
void ListTraverse(); //遍歷節點
private:
int first;
int avail;
int m_Length;
Node<T> SList[MaxSize];
};
template<typename T>
staticLink<T>::staticLink(T a[],int n) {
for (int i = 0; i < MaxSize; i++)
{
SList[i].next = i + 1;
}
m_Length = 0;
SList[MaxSize - 1].next = -1;
avail = 2;
first = 1;
SList[first].next = -1;
//利用頭插法插入元素
for (int j = 0; j < n;j++) {
//判斷鏈中是否已滿
if (avail==-1) {
break;
}
int s = avail;
//空鏈後移
avail = SList[avail].next;
//新鏈上值
SList[s].data = a[j];
//上鍊
SList[s].next = SList[first].next;
SList[first].next = s;
m_Length++;
}
}
template<typename T>
staticLink<T>::~staticLink() {
}
template<typename T>
int staticLink<T>::Length() {
return m_Length;
}
template<typename T>
T staticLink<T>::Get(int i) {
if (i <= 0 || i > m_Length) {
throw"";
}
int s = first;
for (int j = 0; j < i; j++) {
s = SList[s].next;
}
return SList[s].data;
}
template<typename T>
int staticLink<T>::Locate(T x) {
int count = 0;
int s = first;
while (count<m_Length&&SList[s].next!=-1)
{
if (SList[s].data == x) {
return count;
}
count++;
s = SList[s].next;
}
return -1;
}
template<typename T>
bool staticLink<T>::Insert(int i, T x) {
if (SList[avail].next==-1) {
return false;
}
int s = first;
int temp = avail;
SList[temp].data = x;
//空鏈頭針後移
avail = SList[avail].next;
int count=0;
while (count < i-1 &&count < m_Length) {
s = Slist[s].next;
count++;
}
SList[temp].next = SList[s].next;
Slist[s].next = temp;
m_Length++;
return true;
}
template<typename T>
bool staticLink<T>::Delete(int i) {
if (i <= 0 || i > m_Length) {
return false;
}
int count = 0;
int s = first;
while (count < i-1&&count < m_Length) {
s = SList[s].next;
count++;
}
int q = SList[s].next;
SList[s].next = SList[q].next;
SList[q].next = avail;
avail = q;
m_Length--;
return true;
}
template<typename T>
bool staticLink<T>::InsertHead(T x) {
int s = avail;
SList[s].data = x;
avail = SList[avail].next;
SList[s].next = SList[first].next;
SList[first].next = s;
m_Length++;
return true;
}
template<typename T>
bool staticLink<T>::InsertTail(T x) {
int s = first;
int temp = avail;
SList[temp].data = x;
avail = SList[avail].next;
while (SList[s].next != -1) {
s = SList[s].next;
}
SList[temp].next = SList[s].next;
SList[s].next = temp;
m_Length++;
return true;
}
template<typename T>
void staticLink<T>::ListTraverse() {
int s = SList[first].next;
for (int i = 1; i <= m_Length; i++) {
cout << SList[s].data << ",";
s = SList[s].next;
}
}
注意:實現代碼中沒有詳細的註釋,但是其實現方法中的思想及處理方法都與前面的順序表及單鏈表相似,可以類比
//實例調用:
#include<iostream>
#include"staticLink.h"
using namespace std;
int main() {
int a[5] = { 1,2,3,4,5 };
staticLink<int> MyList(a, 5);
MyList.ListTraverse();
cout<<endl<<"第 1個節點的元素是:"<<MyList.Get(1);
MyList.Delete(1);
cout << endl;
MyList.ListTraverse();
cout << endl;
MyList.InsertHead(6);
MyList.InsertTail(5);
MyList.ListTraverse();
cout <<endl<< "鏈表的長度爲:" << MyList.Length();
cout << endl << "元素6所在的位置爲:" << MyList.Locate(6);
return 0;
}
這裏是基本實現,具體的使用技巧應該到具體的問題中體現出來。
以上。