【數據結構】單鏈表基本操作(C++實現)

代碼主體使用結構體+類+模板進行實現。

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;
}

4.運行截圖

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章