C++的链表与Java链表不太一样,后者有垃圾回收机制,C++需要自己delete节点,以防内存泄露。
头文件 :chain.h
#pragma once
#include<iostream>
using namespace std;
template<class T>
struct chainNode
{
T element;
chainNode<T> *next;
chainNode() {};
chainNode(const T &element)
{
this->element = element;
this->next = NULL;
}
chainNode(const T &element, chainNode<T> *next)
{
this->element = element;
this->next = next;
}
};
template<class T>
class chain
{
public:
chain();
~chain();
bool empty()const { return listsize == 0; }
void insert(int index, const T element);
void get();
void delete_data(T data);
void clear();
void delete_node_position(int position);
int getSize() { return listsize; }
void push_back(const T & element);
protected :
int listsize;
chainNode<T> *firstNode;
private:
};
template<class T>
chain<T>::chain()
{
firstNode = NULL;
listsize = 0;
}
template<class T>
chain<T>::~chain()
{
}
template<class T>
void chain<T>::insert(const int index,const T element)
{
if (index > listsize)
cout << "超出范围" << endl;
else
{
if (index == 1)
{
chainNode<T> *p = new chainNode<T>(element, firstNode);
firstNode = p;
}
else {
chainNode<T> *temp = firstNode;
for (int i =1; i < index-1; i++)
{
temp = temp->next;
}
chainNode<T> * target = new chainNode<T>(element, temp->next);
temp->next = target;
}
listsize++;
}
}
template<class T>
void chain<T> ::delete_data(const T data)
{
chainNode<T> *temp = firstNode;
if (firstNode->element == data)
{
temp = temp->next;
delete firstNode;
firstNode = temp;
listsize--;
}
while (temp!=NULL)
{
if (temp->next!=NULL&& temp->next->element == data)
{
chainNode<T> *a = temp->next;
temp->next = a->next;
delete a;
listsize--;
}
temp = temp->next;
}
}
template<class T>
void chain<T>::delete_node_position (const int position)
{
chainNode<T> *temp = firstNode;
if (position == 1)
{
temp = firstNode->next;
delete firstNode;
firstNode = temp;
}
else
{
for (int i = 1; i <position-1; i++)
{
temp = temp->next;
}
chainNode<T>* u = temp->next;
temp->next = temp->next->next;
delete u;//一个数组,如果又有一个指针指向他,随后释放,那么数组还存在吗?
}
}
template<class T>
void chain<T>::clear()
{
//从头向尾删除链表的所有节点
while (firstNode!=NULL)
{
chainNode<T> *temp = firstNode->next;//终有一次,temp会指向firstNode的后面,NULL
delete firstNode;
firstNode = temp;
}
listsize = 0;
}
template<class T>
void chain<T>::push_back(const T &element)
{
chainNode<T> *p = new chainNode<T>(element);
chainNode<T> *current = firstNode;
if (firstNode == NULL)
{
firstNode = p;
}
else
{
while (current ->next!= NULL)
{
current = current->next;
}
current->next = p;
}
listsize++;
}
template<class T>
void chain<T>::get()
{
chainNode<T> *p = firstNode;
while (p != NULL)
{
cout << p->element << " ";
p = p->next;
}
cout << endl;
}
main函数
#include<iostream>
#include "chain.h"
using namespace std;
void show() {
cout << "链表实验 " << endl;
cout << "1.向后插入数据" << endl;
cout << "2.在指定位置插入数据" << endl;
cout << "3.删除某一位置的数据" << endl;
cout << "4.删除指定数据" << endl;
cout << "5.显式链表的容量" << endl;
cout << "6.删除此链表" << endl;
cout << "7.打印此链表" << endl;
cout << "8.退出程序" << endl;
}
void back()
{
string a;
cout << "按确认键返回" << endl;
cin.get();
cin.get();
system("cls");
show();
}
int main()
{
chain<int> curr;
int index;
show();
while (true)
{
cout << "请输入操作数";
cin >> index;
switch (index)
{
case 1:
int nums;
cout << "请输入要插入的数据" << endl;
cin >> nums;
curr.push_back(nums);
back();
break;
case 2:
//在指定位置插入数据
int position;
cout << "请输入要插入的位置和要插入的数据" << endl;
cin >> position >> nums;
curr.insert(position, nums);
back();
break;
case 3:
//删除某一位置的数据
cout << "请输入要删除的位置" << endl;
cin >> position;
curr.delete_node_position(position);
back();
break;
case 4:
//删除指定数据
cout << "请输入要删除的数据" << endl;
cin >> nums;
curr.delete_data(nums);
back();
break;
case 5:
//显式链表的容量
cout << curr.getSize() << endl;
break;
case 6:
curr.clear();
back();
//删除这个链表
break;
case 7:
//打印链表
curr.get();
back();
break;
case 8:
//返回
return 0;
break;
}
}
system("pause");
}
这个链表是最简单的一种链表,介绍一下其他的链表:
①循环链表:在链表的头部加一个头结点,链表的尾巴连接着头结点。空链表中,只有这么一个空链表。 循环链表的优秀在于查询。直接将数据赋给头结点,从第一个节点开始查询时,如果最终在头结点中查到,那么说明链表中不存在target
②双向链表:节点有两个指针,一个指向前方节点,另一个指向后方节点。