1.Node.h文件
//节点类声明
//成员变量:一个int型数据成员,一个指向Node型指针
//成员函数:构造、析构、设置int、返回int、设置link、返回link、打印int
#ifndef NODE_H
#define NODE_H
#include <cstdio>
class LinkList;
class Node
{
friend class LinkList;
public:
Node(int data=0,Node *p=NULL); //带缺省值构造函数
~Node(){} //构析函数暂时不写
void set_data(int i); //设置int
int put_data(); //返回int
void set_link(Node *p); //设置link
Node* put_link(); //返回link
void show(); //打印int
private:
int data; //数据成员
Node *link; //指针
};
#endif
2.Node.cpp文件
//节点类实现
#include <iostream>
#include "Node.h"
using namespace std;
Node::Node(int data,Node *p)
{
this->data=data;
this->link=p;
}
void Node::set_data(int i)
{
data=i;
}
int Node::put_data()
{
return data;
}
void Node::set_link(Node *p)
{
link = p;
}
Node* Node::put_link()
{
return link;
}
void Node::show()
{
cout<<data;
}
3.LinkList.h文件
//链表类声明
//成员变量:一个指向Node型的头指针,带尾节点
//成员函数:构造(带头节点)、判空、求长、添加节点、查找、打印
#ifndef LINKLIST_H
#define LINKLIST_H
#include "Node.cpp"
class LinkList
{
public:
LinkList(); //构造函数
~LinkList(){} //析构函数
bool IsEmpty(); //判空
int Length(); //求长
void addNode(int a); //尾插法添加节点
bool Find(int k,int &i); //查找第k个节点
int Search(const int &i); //搜索i值节点
bool Delete(int k); //删除第k个节点
void show(); //打印
private:
Node *first;
};
#endif
4.LinkList.cpp文件
//链表类实现
#include <iostream>
#include "LinkList.h"
using namespace std;
//构造函数、 带头节点、值为0
LinkList::LinkList()
{
Node *p = new Node;
first = p;
}
//判空
bool LinkList::IsEmpty()
{
return (first->put_link()==NULL)? true : false ;
}
//求表长
int LinkList::Length()
{
Node *p = first;
int i=0;
while(p->put_link())
{
i++;
p=p->put_link();
}
return i;
}
//尾插法添加节点
void LinkList::addNode(int i)
{
Node *p = new Node(i,NULL);
Node *q = first;
while(q->put_link())
{
q=q->put_link();
}
q->set_link(p);
}
//查找第k个节点
bool LinkList::Find(int k,int &x)
{
Node *p=first;
int i=0;
while(p->put_link()&&i<k)
{
p=p->put_link();
i++;
}
if(i==k)
{
x=p->put_data();
return true;
}
return false;
}
//查找x值节点,查找成功返回位置,查找失败返回0
int LinkList::Search(const int &x)
{
Node *p=first;
int i=0;
while(p->put_link())
{
i++;
p=p->put_link();
if(p->put_data()==x)
return i;
}
return 0;
}
//删除第k个节点
bool LinkList::Delete(int k)
{
Node *q=first;
int i=0;
while(q->put_link()&&i<k-1)
{
i++;
q=q->put_link();
}
Node *p = q->put_link();
if(i==k-1&&p)
{
q->set_link(p->put_link());
delete p;
return true;
}
else
{
cout<<"delete error"<<endl;
return false;
}
}
//打印全表
void LinkList::show()
{
Node *p=first;
while(p->put_link())
{
p=p->put_link();
cout<<p->data<<' ';
}
cout<<endl;
}
5.test.cpp文件
//测试文件
#include <iostream>
#include "LinkList.cpp"
using namespace std;
int main()
{
//构造函数
LinkList *L = new LinkList;
//判空
if(L->IsEmpty()) cout<<"Yes,it's Empty"<<endl;
else cout<<"NO,it is not Empty"<<endl;
//添加节点&&求长
L->addNode(21);
L->addNode(12);
L->addNode(50);
if(L->IsEmpty()) cout<<"Now,it's Empty"<<endl;
else cout<<"Now,it is not Empty"<<endl;
cout<<"the length is :"<<L->Length()<<endl;
//查找第1个节点
int temp=0;
if(L->Find(1,temp)) cout<<"the 1th data is:"<<temp<<endl;
//删除&&打印全表
L->Delete(2);
L->show();
}
文本输出:
Yes,it’s Empty
Now,it is not Empty
the length is :3
the 1th data is:21
21 50
<1>
以后不再在节点类中把访问私有成员变量的操作写成函数了,反正也把数据结构类定义成友元了,用成员函数来写总觉得其实并没有什么用,还显得很繁琐复杂。
<2>
这是暂时的一点感悟,像链表这样的数据结构,可能还比较考察C++的基本语法。
等到对类型的概念,对指针和地址的概念,对分配内存的概念深一点以后,这个并不很抽象的结构就能写出来了。
像我一开始总是不知道那个first到底是指针还是节点?到底代表着什么?
现在我的理解是,first是一个指向Node类的指针,在一个实例化的链表类对象中,是一个唯一的私有成员。该对象就可以通过这个指针,顺着一条链访问到整个链表。
而通常在链表类构造函数中,用new先开辟一个内存空间来存放一个无名Node对象,然后这个new语句返回该无名对象的初始地址,这个地址其实就是一个指向Node对象的指针,那么就将它赋值给first。
这样一来就可以通过first访问这第一个Node对象的成员,数据成员和一个又指向Node类的指针,然后就可以继续new Node对象通过指针,这样一个接一个连接起来。成为一个链表。
而真正实现的代码其实大同小异,一个操作每个人有每个人的写法,能够实现出来了就行,实际运用时还是要根据需要去设计。