代碼主體使用結構體+類+模板進行實現。
1.LinkList.h
//LinkList.h
#pragma once
#include<iostream>
using namespace std;
template<class T>
struct Node //結點結構
{
T data; //結點數據域
Node*link;//指針域
Node() { link = NULL; }
Node(T e, Node *next = NULL)
{
data = e;
link = next;
}
};
template<class T>
class LinkList //帶表頭結點的單鏈表類
{
private:
Node<T> *head; //鏈表指針
public:
LinkList(); //構造帶表頭結點的空單鏈表
LinkList(T data[], int mSize);//構造有mSize個元素的單鏈表
~LinkList() { Clear(); } //析構函數
bool Insert(int pos, const T&x); //在單鏈表第pos個元素前插入元素x
bool Remove(int pos, T&x); //刪除單鏈表第pos個元素
bool Replace(int pos, const T&x); //將修改單鏈表第pos個元素爲x
int Length()const; //求表長等不改變數據值,只是讀取建議使用常函數const末尾標識
bool IsEmpty() const; //判空操作
void Clear(); //清空操作
void Output() const; //輸出鏈表
bool search(const T&x) const;//查找元素x在表中是否存在
};
3單鏈表.cpp
//單鏈表.cpp
#include"LinkList.h"
#include<iostream>
using namespace std;
template<class T>
LinkList<T>::LinkList() {//初始化鏈表
head = new Node<T>;
head->link = NULL;
}
template<class T>
LinkList<T>::LinkList(T data[], int mSize) {//初始化鏈表元素
head = new Node<T>;
head -> link = NULL;
head->data = data[0];
Node < T> *end = head;
for (int i = 0; i < mSize; i++)
{
Node<T> *p = new Node<T>;
p->data = data[i];
p->link = NULL;
end->link = p;
end = p;
}
}
template<class T>
bool LinkList<T>::Insert(int pos, T&x) {//插入元素
int cont = 1;
Node<T>*p = head;//初始指向頭節點
bool flag = false;//初始flag爲false
while (p != NULL && cont <= pos - 1)
{
if (cont == pos - 1)//如果p在目標節點處
{
Node<T> *add = new Node<T>;//增加節點add
add->data = x;//新增節點數據域設爲x
add->link = p->link;//指針域指向原來p所指向的位置
p->link = add;//p重新指向add新增節點
flag = true;
break;
}
else {//如果沒到目標節點,指針一直移動並且計數器++
cont++;
p = p->link;
}
}
return flag;
}
template<class T>
bool LinkList<T>::Remove(int pos, T&x)//刪除元素
{
int cont = 1;
Node<T> *p = head;//p指向頭節點
bool flag = false;
while (p!=NULL&&cont<=pos-1)
{
if (cont == pos - 1)
{
Node<T> *del = p->link;
p->link=p->link->link;//刪除節點(2)後p指向初始節點(1)後面(2)的後面那個元素(3)
x = del->data;
delete del;
flag = true;
break;
}
else
{
cont++;
p = p->link;
}
}
return flag;
}
template<class T>
bool LinkList<T>::Replace(int pos, T&x)//修改元素
{
int cont = 1;
Node<T>* p = head;
bool flag = false;
while (p != NULL && cont <= pos)
{
if (cont == pos)
{
p->data = x;
flag = true;
}
else
{
cont++;
p = p->link;
}
}
return flag;
}
template<class T>
int LinkList<T>::Length()const//求表長
{
int cont = 0;
Node<T>*p = head;
while (p != NULL)
{
cont++;
p = p->link;
}
return cont;
}
template<class T>
void LinkList<T>::Clear() {//清空鏈表
if (head != NULL) {
Node<T> *p;
p = head->link;
while(p != NULL) {
Node<T> *del = p;
p = p->link;
delete del;
}
head = NULL;
}
}
template<class T>
bool LinkList<T>::IsEmpty()const//判空
{
return head == NULL;//HEAD爲空則返回true
}
template<class T>
bool LinkList<T>::Search(const T&x)const//查詢
{
bool flag = false;
Node<T>*p = head;
while (p!=NULL)
{
if (p->data == x)
{
flag = true;
break;
}
else
{
p = p->link;
}
}
return flag;
}
template<class T>
void LinkList<T>::OutPut()const//輸出鏈表
{
Node<T> *p = head;
int cont = 0;
while (p != NULL)\
{
cout << p->data << ",";
p = p->link;
cont++;
if (cont % 10 == 0)
{
cout << endl;
}
}
cout << endl;
}
3.測試.cpp
//測試.cpp
#include"單鏈表.cpp"
#include<ctime>
void menu()//模擬菜單選項
{
cout << "********************************************************" << endl;
cout << "* 1 ------------輸出鏈表 *" << endl;
cout << "* 2 ------------插入元素 *" << endl;
cout << "* 3 ------------刪除元素 *" << endl;
cout << "* 4 ------------銷燬鏈表 *" << endl;
cout << "* 5 ------------查找 *" << endl;
cout << "* 0 ------------退出系統 *" << endl;
cout << "********************************************************" << endl;
}
const int N = 20;
int main()
{
srand((unsigned)time(NULL));//以系統當前時間初始化隨機數發生器
int data[N];
for (int i = 0; i < N; i++)
data[i] = rand() % 100;//用隨機數發生器產生100以內的整數
LinkList<int> L(data, N);//創建N個元素的單鏈表
menu();
while (1) //模擬菜單工作方式
{
int select;
cout << "請輸入您的選擇:";
cin >> select;
switch (select)
{
case 1: //輸出單鏈表
if (L.IsEmpty())
{
cout << "鏈表爲空!" << endl;
}
else
L.OutPut();
break;
case 2: //插入
int pos, elem;
cout << "請輸入插入位置:";
cin >> pos;
cout << "插入元素:";
cin >> elem;
if (L.Insert(pos, elem)) //插入成功
cout << "在第" << pos << "個元素前成功插入" << elem << endl;
else //插入失敗
cout << "插入位置不合法!" << endl;
break;
case 3: //刪除
cout << "請輸入刪除位置:"; cin >> pos;
int x;
if (L.Remove(pos, x))//刪除單鏈表的第pos個元素
cout << "單鏈表的第" << pos << "個元素" << x << "已被刪除。" << endl;
else
cout << "刪除位置不合法!" << endl;
break;
case 4: //銷燬鏈表
char OK;
cout << "確定要銷燬鏈表嗎?(y/n)" << endl;
cin >> OK;
if (OK == 'y' || OK == 'Y') L.Clear();
break;
case 5: //查找
cout << "請輸入查找元素:";
cin >> elem;
if (L.Search(elem))
cout << "查找成功!" << endl;
else
cout << "查找失敗!" << endl;
break;
case 0: //退出
exit(0);
default:
cout << "您輸入的選項有誤,請重新輸入:";
}
}
return 0;
}