您的位置:首页 > 编程语言 > C语言/C++

带头结点的单链表实现(C++)

2014-08-13 16:26 405 查看
单链表在插入和删除操作时,有无头结点的实现是有区别的,总的来说,带有头结点的单链表实现起来比较方便,而不带头结点的单链表在链首插入和删除时要特殊处理,以下代码是带有头结点的单链表的实现。

//类定义、模板类的定义

#ifndef IncludeHeadNodeChain_H_H
#define IncludeHeadNodeChain_H_H
#include <iostream>
using std::ostream;
//自定义一个异常类,用于查找、插入和删除操作中越界时的异常提示
class OutOfBounds
{
public:
void msg()
{std::cout<<"越界"<<std::endl;}
};

template <class T>
class Node
{
private:
//声明友元类
template <class T>
friend class IncludeHeadNodeChain;
//定义节点数据
T data;//数据域
Node<T> * next;//指针域
};

template <class T>
class IncludeHeadNodeChain
{
private:
Node<T> * head;
public:
IncludeHeadNodeChain();
~IncludeHeadNodeChain();
bool isEmpty() const;
bool find_k(int k, T& x) const;//用于发现第k个元素,返回给x
int search_x(const T& x) const;//用于查找链表中是否有元素x,并返回x的位置
int length() const {return head->data;}//返回链表长度
IncludeHeadNodeChain<T>& insert(int k, const T& x);
IncludeHeadNodeChain<T>& del(int k, T& x);
void output(ostream& os) const;
//友元类,用于输出链表元素
template <class T>
friend ostream& operator<<(ostream& os, const IncludeHeadNodeChain<T>& ihnc);
};

template <class T>
IncludeHeadNodeChain<T>::IncludeHeadNodeChain()
{
//创建头结点
head = new Node<T>;
head->next = NULL;
head->data = 0;//本例中头结点的数据域用于存放链表长度
}

template <class T>
IncludeHeadNodeChain<T>::~IncludeHeadNodeChain()
{
Node<T> * cur = head;
while (head)
{
cur = cur->next;
delete head;
head = cur;
}
}

template <class T>
bool IncludeHeadNodeChain<T>::isEmpty() const
{
return head->next == NULL;
}

template <class T>
bool IncludeHeadNodeChain<T>::find_k(int k, T& x) const
{
if (k < 0)
throw OutOfBounds();
Node<T> * cur = head;//cur最终指向第k个元素

for (int i = 0;i < k && cur;i++)
cur = cur->next;
if (!cur)
return false;
x = cur->data;
return true;
}

template <class T>
int IncludeHeadNodeChain<T>::search_x(const T& x) const
{
Node<T> * cur = head->next;
int index = 1;
while (cur && cur->data != x)
{
cur = cur->next;
index++;
}
if (!cur)
return -1;//返回-1表示未能找到x
return index;
}

template <class T>
IncludeHeadNodeChain<T>& IncludeHeadNodeChain<T>::insert(int k, const T& x)
{
if (k < 0)
throw OutOfBounds();
Node<T> * cur = head;
for (int i = 0;i < k && cur;i++)
cur = cur->next;
if (k > 0 && !cur)//若不存在第k个元素
throw OutOfBounds();
Node<T> * ins = new Node<T>;//带插入元素
ins->data = x;
//执行插入操作
ins->next = cur->next;
cur->next = ins;

head->data++;//链表长度加1
return *this;
}

template <class T>
IncludeHeadNodeChain<T>& IncludeHeadNodeChain<T>::del(int k, T& x)
{
if (k < 1) throw OutOfBounds();
Node<T> * pre = head;//pre最终指向第k个元素的上一个元素
for (int i = 0;i < k-1 && pre;i++)
pre = pre->next;
if (!pre || !pre->next)
throw OutOfBounds();
Node<T> * cur = pre->next;//cur指向第k个元素
//执行删除操作
pre->next = cur->next;
x = cur->data;
delete cur;

head->data--;//链表长度减1
return *this;
}

template <class T>
void IncludeHeadNodeChain<T>::output(ostream& os) const
{
Node<T> * cur = head->next;//cur指向第一个节点
while (cur)
{
std::cout<<cur->data<<" ";
cur = cur->next;
}
std::cout<<std::endl;
}

template <class T>
ostream& operator<<(ostream& os, const IncludeHeadNodeChain<T>& ihnc)
{
ihnc.output(os);
return os;
}
#endif
使用以下代码进行测试:

#include <iostream>
#include "linkedlist.h"

int main()
{
using std::cout;
using std::endl;

IncludeHeadNodeChain<int> chain;
try
{
chain.insert(0,4);
chain.insert(1,56);
chain.length();
//下面代码将出现异常
int x;
chain.del(3,x);
}
catch(OutOfBounds& o)
{o.msg();}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: