SingleLinkList.h
#pragma once
template <class DataType>
struct Node
{
DataType data;
Node<DataType> *next;
};
//注:头结点不作为数据结点使用,其存储的first->data是单链表的长度,因此单链表的长度是不计算头结点的。
template <class DataType>
class SingleLinkList
{
public:
SingleLinkList();//无参数构造函数
SingleLinkList(DataType a[], int n);//有参数构造函数:用含n个元素的数组采用前插法初始化单链表【始终将新建结点插入在头结点和第一个结点之间】
SingleLinkList(int n, DataType a[]);//有参数构造函数:用含n个元素的数组采用尾接法初始化单链表【始终将新建结点插入作为单链表的最后一个结点】【建议使用该法】
~SingleLinkList();//析构函数
int GetLength();//获得单链表长度
bool IsEmpty();//判断单链表是否为空
DataType GetValueByLocation(int i);//按位查找返回单链表的第i个元素
DataType DeleteByLocation(int i);//删除单链表的第i个元素并返回删除的值
DataType DeleteAtHead();//删除头部元素并返回删除的值
DataType DeleteAtTail();//删除尾部元素并返回删除的值
DataType GetMaxElement();//获得单链表的最大元素
DataType GetMinElement();//获得单链表的最小元素
Node<DataType> *GetFirst();//获得单链表的头指针
void MergeIncrementally(SingleLinkList<DataType>* LA, SingleLinkList<DataType>* LB, SingleLinkList<DataType>* LC);//递增地合并单链表LA和LB到LC
void Insert(int i, DataType x);//按位插入元素
void InsertAtHead(DataType x);//在头部插入元素
void InsertAtTail(DataType x);//在尾部插入元素
void PrintSingleLinkList();//遍历单链表
void ClearSingleLinkList();//清空单链表
void ReverseSingleLinkList();//倒置【反转】单链表
void SetValueAtLocation_iBy_x(int i, DataType x);//设置位置i的元素的值为x
void SortSingleLinkList();//把单链表从小到大排序
private:
Node<DataType> *first;
};
template<class DataType>
inline SingleLinkList<DataType>::SingleLinkList()
{
first = new Node<DataType>;
first->next = NULL;
first->data = 0;
}
template<class DataType>
inline SingleLinkList<DataType>::SingleLinkList(DataType a[], int n)//每次把新建结点作为第一结点
{
first = new Node<DataType>;
Node<DataType> *s;
first->next = NULL;
for (int i = 0; i < n; i++) {
s = new Node<DataType>;
s->data = a[i];
s->next = first->next;
first->next = s;
}
first->data = n;
}
template<class DataType>
inline SingleLinkList<DataType>::SingleLinkList(int n, DataType a[])//每次把新建结点作为最后结点
{
first = new Node<DataType>;
first->next = NULL;
Node<DataType> *temp = first;//temp作为尾指针
Node<DataType> *s;
for (int i = 0; i < n; i++) {
s = new Node<DataType>;
s->data = a[i];
temp->next = s;
temp = s;
}
temp->next = NULL;
first->data = n;
}
template<class DataType>
inline SingleLinkList<DataType>::~SingleLinkList()
{
Node<DataType> *p = first;
while (p) {
Node<DataType> *q = p;
p = p->next;
delete q;
}
}
template<class DataType>
inline int SingleLinkList<DataType>::GetLength()
{
return first->data;
}
template<class DataType>
inline bool SingleLinkList<DataType>::IsEmpty()
{
if (first->data == 0 || first->next == NULL)
return true;
else return false;
}
template<class DataType>
inline DataType SingleLinkList<DataType>::GetValueByLocation(int i)
{
if (i > first->data || IsEmpty()) {
cout << "delete error!" << endl;
return -1;
}
Node<DataType> *p = first->next;
for (int j = 1; j < i; p = p->next) {
j++;
}
return p->data;
}
template<class DataType>
inline DataType SingleLinkList<DataType>::DeleteByLocation(int i)
{
if (i > first->data || IsEmpty()) {
cout << "delete error!" << endl;
return -1;
}
int j = 1;
Node<DataType> *q = first;
Node<DataType> *p = first->next;
while (j < i)
{
q = p;
p = p->next;
j++;
}
q->next = p->next;
DataType temp = p->data;
first->data--;
delete p;
return temp;
}
template<class DataType>
inline DataType SingleLinkList<DataType>::DeleteAtHead()
{
if (IsEmpty()) {
return -1;
}
Node<DataType> *p = first->next;
first->next = p->next;
DataType temp = p->data;
first->data--;
delete p;
return temp;
}
template<class DataType>
inline DataType SingleLinkList<DataType>::DeleteAtTail()
{
if (IsEmpty()) {
return -1;
}
Node<DataType> *p = first;
Node<DataType> *q = first->next;
while (q->next)
{
p = q;
q = q->next;
}
p->next = NULL;
DataType temp = q->data;
first->data--;
delete q;
return temp;
}
template<class DataType>
inline DataType SingleLinkList<DataType>::GetMaxElement()
{
if (IsEmpty()) {
cout << "get error!" << endl;
return -1;
}
Node<DataType> *p = first->next;
DataType max = p->data;
for (p = p->next; p != NULL; p = p->next) {
if (p->data > max) {
max = p->data;
}
}
return max;
}
template<class DataType>
inline DataType SingleLinkList<DataType>::GetMinElement()
{
if (IsEmpty()) {
cout << "get error!" << endl;
return -1;
}
Node<DataType> *p = first->next;
DataType min = p->data;
for (p = p->next; p != NULL;p = p->next) {
if (p->data < min) {
min = p->data;
}
}
return min;
}
template<class DataType>
inline Node<DataType>* SingleLinkList<DataType>::GetFirst()
{
if (first->data == 0 || IsEmpty()) {
cout << "get error!" << endl;
return nullptr;
}
return first;
}
template<class DataType>
inline void SingleLinkList<DataType>::MergeIncrementally(SingleLinkList<DataType> *LA, SingleLinkList<DataType> *LB, SingleLinkList<DataType> *LC)
{
LA->SortSingleLinkList();//首先使得LA,LB变成递增有序.
LB->SortSingleLinkList();
Node<DataType> *pa, *pb, *s, *r;
int count = 0;
pa = LA->first->next;
pb = LB->first->next;
r = LC->first;//r当前作为LC的头结点
while (pa && pb)
{
if (pa->data <= pb->data)
{
s = new Node<DataType>;
s->data = pa->data;
r->next = s;
pa = pa->next;
r = s;
count++;
}
else
{
s = new Node<DataType>;
s->data = pb->data;
r->next = s;
pb = pb->next;
r = s;
count++;
}
}
while (pa)
{
s = new Node<DataType>;
s->data = pa->data;
r->next = s;
pa = pa->next;
r = s;
count++;
}
while (pb)
{
s = new Node<DataType>;
s->data = pb->data;
r->next = s;
pb = pb->next;
r = s;
count++;
}
r->next = NULL;
LC->first->data = count;
}
template<class DataType>
inline void SingleLinkList<DataType>::Insert(int i, DataType x)
{
if (i > first->data+1 ) {
cout << "insert error!" << endl;
return;
}
int j = 1;
Node<DataType> *q = first;
Node<DataType> *p = first->next;
while (j < i)
{
q = p;
p = p->next;
j++;
}
Node<DataType> *temp = new Node<DataType>;
temp->data = x;
q->next = temp;
temp->next = p;
first->data++;
}
template<class DataType>
inline void SingleLinkList<DataType>::InsertAtHead(DataType x)
{
Node<DataType> *temp = new Node<DataType>;
temp->data = x;
temp->next = first->next;
first->next = temp;
first->data++;
}
template<class DataType>
inline void SingleLinkList<DataType>::InsertAtTail(DataType x)
{
Node<DataType> *q = first->next;
while (q->next)
{
q = q->next;
}
Node<DataType> *temp = new Node<DataType>;
q->next = temp;
temp->next = NULL;
temp->data = x;
first->data++;
}
template<class DataType>
inline void SingleLinkList<DataType>::PrintSingleLinkList()
{
if (first->data == 0 || IsEmpty()) {
cout << "print error!" << endl;
return;
}
int j=0;
Node<DataType> *q = first->next;
while (q)
{
cout << q->data << " ";
q = q->next;
j++;
if (j % 50 == 0)
cout << endl;
}
cout << endl;
}
template<class DataType>
inline void SingleLinkList<DataType>::ClearSingleLinkList()
{
Node<DataType> *p;
Node<DataType> *q = first->next;
while (q)
{
p = q;
q = q->next;
delete p;
}
first->next = NULL;
first->data = 0;
}
template<class DataType>
inline void SingleLinkList<DataType>::ReverseSingleLinkList()
{
if (IsEmpty())
return;
Node<DataType> *previos, *current, *back;
current = first->next;
back = current->next;
while (back)
{
previos = current;
current = back;
back = back->next;
current->next = previos;
}
first->next->next = NULL;
first->next = current;
}
template<class DataType>
inline void SingleLinkList<DataType>::SetValueAtLocation_iBy_x(int i, DataType x)
{
if (i > first->data || IsEmpty()) {
cout << "set error!" << endl;
return;
}
int j = 1;
Node<DataType> *p = first->next;
while (j < i)
{
p = p->next;
j++;
}
p->data = x;
}
template<class DataType>
inline void SingleLinkList<DataType>::SortSingleLinkList()
{
if (IsEmpty()) {
cout << "sort error!" << endl;
return;
}
int i;
int N = first->data;
DataType *arr = new DataType[N];
Node<DataType> *p = first->next;
for (i=0; p != NULL; p = p->next,i++) {//先把所有结点的数据提取到一个数组arr中存储
arr[i] = p->data;
}
DataType temp;
for (i = 1; i < N; i++) { //选用插入排序对数组arr从小到大排序
for (int j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
for (i = 0,p=first->next; p != NULL; p = p->next, i++) {//为每个结点从小到大赋值
p->data = arr[i];
}
delete[] arr;
}
SingleLinkListTest.cpp
测试平台: Visual Studio 2015
#include<iostream>
#include"SingleLinkList.h" //若把此两个的头文件顺序互换,会出现何种情况?
using namespace std;
void main()
{
int a[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 };
int b[] = { -9,6,88,-7,-91,52,33,20,15,-44 };
SingleLinkList<int> Test1(a, sizeof(a) / sizeof(a[0]));//前插法初始化单链表
cout << "打印前插法初始化的单链表:";
Test1.PrintSingleLinkList();
cout << " 获得单链表1的长度:" << Test1.GetLength() << endl;
SingleLinkList<int> Test2(sizeof(b) / sizeof(b[0]),b);//尾接法初始化单链表
cout << "打印尾接法初始化的单链表:";
Test2.PrintSingleLinkList();
cout << " 获得单链表2的长度:" << Test2.GetLength() << endl;
cout << " 获得单链表2的最大值:" << Test2.GetMaxElement() << endl;
cout << " 获得单链表2的最小值:" << Test2.GetMinElement() << endl;
cout << " 单链表2删除头部元素:" << Test2.DeleteAtHead() << endl;
cout << " 单链表2删除尾部元素:" << Test2.DeleteAtTail() << endl;
cout << " 打印单链表2:";
Test2.PrintSingleLinkList();
cout << " 获得单链表2的长度:" << Test2.GetLength() << endl;
cout << "单链表2位置为4的元素的值:" << Test2.GetValueByLocation(4) << endl;
cout << "单链表2删除位置为7的元素:" << Test2.DeleteByLocation(7) << endl;
cout << " 打印单链表2:";
Test2.PrintSingleLinkList();
cout << " 获得单链表2的长度:" << Test2.GetLength() << endl;
cout << " 单链表2在头部插入元素33:" << endl;
Test2.InsertAtHead(33);
cout << " 单链表2在尾部插入元素-3:" << endl;
Test2.InsertAtTail(-3);
cout << " 打印单链表2:";
Test2.PrintSingleLinkList();
cout << " 获得单链表2的长度:" << Test2.GetLength() << endl;
cout << "设置单链表2中位置为5的元素为333:" << endl;
Test2.SetValueAtLocation_iBy_x(5, 333);
cout << " 倒置【反转】单链表2:" << endl;
Test2.ReverseSingleLinkList();
cout << " 打印单链表2:";
Test2.PrintSingleLinkList();
cout << " 获得单链表2的长度:" << Test2.GetLength() << endl;
cout << " 单链表2排序:" << endl;
Test2.SortSingleLinkList();
cout << " 打印单链表2:";
Test2.PrintSingleLinkList();
cout << " 获得单链表1的最大值:" << Test1.GetMaxElement() << endl;
cout << " 获得单链表1的最小值:" << Test1.GetMinElement() << endl;
cout << " 单链表1删除头部元素:" << Test1.DeleteAtHead() << endl;
cout << " 单链表1删除尾部元素:" << Test1.DeleteAtTail() << endl;
cout << " 打印单链表1:";
Test1.PrintSingleLinkList();
cout << " 获得单链表1的长度:" << Test1.GetLength() << endl;
cout << "单链表1位置为6的元素的值:" << Test1.GetValueByLocation(6) << endl;
cout << "单链表1删除位置为8的元素:" << Test1.DeleteByLocation(8) << endl;
cout << " 打印单链表2:";
Test1.PrintSingleLinkList();
cout << " 获得单链表1的长度:" << Test1.GetLength() << endl;
cout << " 单链表1在头部插入元素11:" << endl;
Test1.InsertAtHead(11);
cout << " 单链表1在尾部插入元素-1:" << endl;
Test1.InsertAtTail(-1);
cout << " 打印单链表1:";
Test1.PrintSingleLinkList();
cout << " 获得单链表1的长度:" << Test1.GetLength() << endl;
cout << "设置单链表1中位置为15的元素为888:" << endl;
Test1.SetValueAtLocation_iBy_x(15, 888);
cout << " 倒置【反转】单链表1:" << endl;
Test1.ReverseSingleLinkList();
cout << " 打印单链表1:";
Test1.PrintSingleLinkList();
cout << " 获得单链表1的长度:" << Test1.GetLength() << endl;
cout << " 单链表1排序:" << endl;
Test1.SortSingleLinkList();
cout << " 打印单链表1:";
Test1.PrintSingleLinkList();
cout << " 打印单链表2:";
Test2.PrintSingleLinkList();
cout << "合并单链表1和2到单链表LC:" << endl;
SingleLinkList<int> LC;
LC.MergeIncrementally(&Test1, &Test2, &LC);
cout << " 打印单链表LC:";
LC.PrintSingleLinkList();
cout << " 获得单链表LC的长度:" << LC.GetLength() << endl;
cout << " 判断单链表1是否为空表:" << Test1.IsEmpty() << endl;
cout << " 清空单链表1:" << endl;
Test1.ClearSingleLinkList();
cout << " 判断单链表1是否为空表:" << Test1.IsEmpty() << endl;
cout << "单链表1删除位置为5的元素:";
Test1.DeleteByLocation(5);
}