您的位置:首页 > 理论基础 > 数据结构算法

经典算法与数据结构的c++实现——带头结点的单链表

2016-06-12 20:17 946 查看


下面是实现的代码(欢迎批评指点,之后会放到github上:https://github.com/y277an/princeton_algs4):

/********** ***************************************************************
// Program Name: Link.h
// Tools: vim
// Language:c++
// Created Time: 2016年06月12日 星期日 08时09分25秒
// Description:包含头结点的单链表
// Author: mseddl
************************************************************************/

#ifndef _LINK_H
#define _LINK_H
#include <iostream>
#include <assert.h>

template<class T>
class CLink
{
public:
T data; //用于保存结点元素的内容
CLink<T> *next; //指向后继结点的指针
CLink(CLink<T>* nextValue=NULL)
{
next = nextValue;
}
CLink(const T info ,CLink<T>* nextValue = NULL)
{
data = info;
next = nextValue;
}
};

template<class T>
class CSingleList:public CLink<T>
{
private:
CLink<T> *head, *tail; //单链表的头、尾指针
int length = 0;
public:
CLink<T> *searchPos(const int p); //返回第p个结点指针:
CSingleList(); //构造函数
~CSingleList(); //析构函数
bool isEmpty(); //判断链表是否为空
void clear(); //将链表存储的内容清除,成为空表,表长度变成0
bool append(const T value); //表尾添加一个元素value,表长度增1
bool insert(const int p,const T value);//位置p上插入一个数值为value的结点,表长度增1
bool remove(const int p); //删除位置p上的元素,成功的话,返回true,表长度减1
bool del(const T value); //删除数值为value的第一个元素,成功的话,返回true,表长度减1
bool getPos(T value); //查找值为value的元素,找到返回true
T getValue(const int p); //返回位置p的数值
bool reverse(); //将链表进行反转,成功的话,返回true
};

template <class T>
CLink<T>* CSingleList<T>::searchPos(const int p) //返回第p个结点指针:
{
int count = 0;
if(p == -1) //i为-1则定位到头结点
return head;
//若i为0,则定位到第一个结点
CLink<T> *m =head ->next;
while(m != NULL && count < p)
{
m = m -> next;
count++;
};
return m;
};

template<class T>
CSingleList<T>::CSingleList() //构造函数
{
head = new CLink<T>();
head -> next = tail;
tail = NULL;
}

template<class T>
CSingleList<T>::~CSingleList() //析构函数
{
if(length != 0)
CSingleList::clear();
delete head;
}

template<class T>
bool CSingleList<T>::isEmpty() //判断链表是否为空
{
if( length == 0) //也可用head -> next == NULL 来判断
{
return true;
}
return false;
}

template<class T>
void CSingleList<T>::clear() //将链表存储的内容清除,成为空表,表长度变成0
{
if(length == 0)
return;
for(int i=0;i<length;i++)
{
CLink<T>*m,*n;
m = head -> next;
n = m -> next;
delete m;
head -> next = n;
}
tail = NULL;
length = 0;
}

template<class T>
bool CSingleList<T>::append(const T value) //表尾添加一个元素value,表长度增1
{
tail =new CLink<T>(value);
CLink<T>* m = searchPos(length - 1);
m -> next = tail;
tail = tail ->next;
tail = NULL;
++length;
}

template<class T>
bool CSingleList<T>::insert(const int p,const T value) //位置p上插入一个数值为value的结点,表长度增1
{
if(p >= length || p < 0)
{
std::cout<<"非法的插入点"<<std::endl;
return false;
}
CLink<T>* m = searchPos(p-1);
CLink<T>* n = new CLink<T>(value);
n->next = m->next ;
m -> next = n;
++length;
return true;
}

template<class T>
bool CSingleList<T>::remove(const int p) //删除位置p上的元素,成功的话,返回true,表长度减1
{
if(p >= length || p < 0)
{
std::cout<<"想要删除的点不存在"<<std::endl;
return false;
}
CLink<T>* m = searchPos(p-1);
CLink<T>* n = m -> next;
m -> next = n -> next;
delete n;
--length;
}
template<class T>
bool CSingleList<T>::del(const T value) //删除数值为value的第一个元素,成功的话,返回true,表长度减1
{
if(length == 0)
return false;
int record_pos = 0;
CLink<T>* m = head -> next;
while(m != tail)
{
if(m->data == value)
{
CLink<T>* n = searchPos(record_pos - 1);
n -> next = m ->next;
delete m;
--length;
return true;
}
m = m -> next;
++record_pos;
}
return false;
}

template<class T>
bool CSingleList<T>::getPos(T value) //查找值为value的元素,找到返回true
{
if(length == 0)
return false;
CLink<T>* m = head -> next;
while(m != tail)
{
if(m->data == value)
{
return true;
}
m = m -> next;
}
}

template<class T>
T CSingleList<T>::getValue(const int p) //返回位置p的数值
{
assert(p >= 0);
assert(p < length);
CLink<T>* m = searchPos(p);
return m -> data;
}

template<class T>
bool CSingleList<T>::reverse() //将链表进行反转,成功的话,返回true
{
if(length <= 1)
{
std::cout<<"链表太短无法反转"<<std::endl;
return false;
}

CLink<T>* pre = head;
CLink<T>* cur = head -> next;
while(cur)
{
CLink<T>* forwd = cur -> next;
if(cur == head -> next)
cur -> next = tail;
else
cur -> next = pre;
pre = cur;
cur = forwd;
}
head -> next = pre;
return true;
}
#endif


下面是测试的主函数代码:
/*************************************************************************
// Program Name: Link_test.cpp
// Tools: vim
// Language:c++
// Created Time: 2016年06月12日 星期日 18时59分36秒
// Description:单链表的测试主程序
// Author: mseddl
************************************************************************/

#include<iostream>
#include"Link.h"
using namespace std;

int main()
{
CSingleList<int> link_one;
link_one.append(5);
link_one.insert(0,4);
link_one.append(3);
link_one.append(2);
link_one.del(3);
link_one.remove(1);
link_one.append(5);
link_one.append(6);
link_one.reverse();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  单链表