今天复习了一下数据结构的基于链表的Chain类,以涉及到指针什么的就感觉晕晕的,但是每一次复习都有每一次的进步,也会有新的理解和体会,除了练习增,删,插的基本操作以外,还写了重载操作符,还有链表的遍历容器类ChainIterator,要坚持下去,加油。
//
// main.cpp
// ChainNodeDemo
//
// Created by xin wang on 4/14/15.
// Copyright (c) 2015 xin wang. All rights reserved.
//
#include <iostream>
class OutOfBounds {
public:
OutOfBounds(){
std::cout<<"out of bounds"<<std::endl;
}
};
class Nomen{
public:
Nomen(){
std::cout<<"Nomen error"<<std::endl;
}
};
//使new引发NoMem异常而不是xalloc异常
//如果要恢复原始行为可以做以下调用
//_set_new_handler(Old_Handler);
int my_new_handler(size_t size){
throw Nomen();
}
template <class T>
class ChainNode {
public:
T data;
ChainNode<T> *link;
};
template <class T>
class Chain{
public:
Chain(){first =0;}//构造函数
~Chain();//析构函数,就是删掉链表中的每一个节点
bool IsEmpty()const {//判断链表是不是没有元素
return first=0;
}
int Length()const;//返回链表的长度
bool Find(int k,T& x)const;//寻找第k个元素并将其放到x中
void Erase();//删除链表中的所有节点
void Output(std::ostream& out) const;//输出链表
int Search(const T& x)const;//寻找是否存在x这个值
Chain<T>& Delete(int k,T& x);//删除节点
Chain<T>& Insert(int k,const T& x);//插入节点
Chain<T>& Append(const T& x);//在链表的最后加上元素
//private: 不用遍历输出的时候,这个地方设置为private,如果是使用遍历输出链表就需要设置为public
ChainNode<T> *last;
ChainNode<T> *first;
};
//析构函数
template <class T>
Chain<T>::~Chain<T>(){
Erase();
}
//返回链表的长度
template <class T>
int Chain<T>::Length()const{
ChainNode<T> *currrent = first;
int len=0;
while (currrent) {
len++;
currrent = currrent->link;//每往下移动一个节点,len就加1;
}
return len;
}
//将第k个元素放在x中
template <class T>
bool Chain<T>::Find(int k, T& x)const{
if (k<1) {
return false;//如果k小于1,就返回
}
ChainNode<T> *current = first;
int index=1;
while (index < k&¤t) {//移动到第k个节点
current = current->link;
index++;
}
if (current) {//如果存在当前节点,取出当前节点的值,放在x中
x=current->data;
return true;
}
return false;
}
//第几个元素是x元素
template <class T>
int Chain<T>::Search(const T& x)const{
ChainNode<T> *current = first;
int index = 1;
while (current && current->data!=x) {//如果存在current节点,并且没有当前元素的值不为x,就往下移动,寻找下一个节点
current=current->link;
index++;
}
if (current) {//如果当前节点存在的话,返回index,表示元素在第index个,如果index为0,说明没有找到
return index;
}
return 0;
}
//删除第k个节点,并将第k个节点的值,放在x中
template <class T>
Chain<T>& Chain<T>::Delete(int k, T& x){
if (k<1 || !first) {//判断k的范围是不是符合条件
throw OutOfBounds();
}
ChainNode<T> *p = first;
if (k==1) {//如果是删除头节点的话,
first = first->link;
}else{//如果不是头节点
ChainNode<T> *q = first;
for (int index =1;index<k-1 && q; index++) {//指向到k个节点的上个节点
q=q->link;
}
if (!q || !q->link) {
throw OutOfBounds();
}
p=q->link;
q->link=p->link;
}
x=p->data;
delete p;
return *this;
}
//输出链表
template<class T>
void Chain<T>::Output(std::ostream& out)const{
ChainNode<T>*current;
for(current=first;current;current=current->link){
out<<current->data;
if(!current->link){
out<<""<<std::endl;
}else{
out<<",";
}
}
}
//重载操作符
template<class T>
std::ostream& operator<<(std::ostream& out,const Chain<T>&x){
x.Output(out);
return out;
}
//插入操作
template <class T>
Chain<T>& Chain<T>::Insert(int k, const T& x){
if(k<0)throw OutOfBounds();
ChainNode<T> *p=first;
for (int index=1;index<k && p; index++) {
p=p->link;//移动到第k个节点
}
if (k>0 && !p) {
throw OutOfBounds();
}
ChainNode<T> *y = new ChainNode<T>();
y->data=x;
if(k){
y->link=p->link;
p->link=y;
}else{
y->link=first;
first=y;
}
return *this;
}
template <class T>
void Chain<T>::Erase(){
ChainNode<T> *next;
while (first) {
next=first->link;
delete first;
first = next;
}
}
template <class T>
Chain<T>& Chain<T>::Append(const T& x){
ChainNode<T> *y = new ChainNode<T>();
y->data = x;
y->link=0;
if (first) {
last->link = y;//代表使last的下一个节点是y
last=y;
}else{
first = last=y;
}
return *this;
}
//遍历器
template <class T>
class ChainIterator{
public:
T* Initialize(const Chain<T>&c){
location = c.first;
if(location){
return &location->data;
}
return 0;
}
T* Next(){
if(!location)
return 0;
location = location->link;
if(location)
return &location->data;
return 0;
}
private:
ChainNode<T>*location; };
int main(int argc, const char * argv[]) {
int count=0;
Chain<int>a;
while(true){
int b;
std::cin>>b;
if (b==0) {
break;
}
count++;
a.Append(b);
}
std::cout<<"lenght:"<<a.Length()<<std::endl;
std::cout<<a<<" "<<std::endl;
std::cout<<"input1"<<std::endl;
int c;
std::cin>>c;
a.Insert(4, c);
std::cout<<a<<" "<<std::endl;
int d;
a.Find(3, d);
std::cout<<"third element"<<d<<std::endl;
std::cout<<"input2"<<std::endl;
int q;
std::cin>>q;
std::cout<<"the number is"<<a.Search(q)<<std::endl;
int m;
a.Delete(3, m);
std::cout<<"after delete"<<a<<" "<<std::endl;
//使用遍历器输出
int *aa;
ChainIterator<int> iter;
aa=iter.Initialize(a);
while (aa) {
std::cout<<*aa;
aa= iter.Next();
if (aa) {
std::cout<<",";
}else{
std::cout<<"";
}
}
return 0;
}