#include <iostream>
#define SIZE 40
using namespace std;
/*实现一个栈,用于后面将链表中的元素先压栈再弹出栈实现反向打印的功能*/
int Stack[SIZE];
int top=0;//栈顶指针
//判空
int is_empty(){
return 0==top;
}
//判满
int is_full(){
return top==SIZE;
}
//压栈
void push(int data){
if(!is_full())
Stack[top++]=data;
else
cout<<"overflow\n";
}
//弹栈
int pop(){
if(!is_empty())
return Stack[--top];
else
cout<<"underflow!\n";
}
/*实现一个带头节点与尾节点的单向链表*/
class List{
public:
//构造函数中初始化为空链表
List(void):m_head(NULL),m_tail(NULL){}
//析构函数中销毁剩余的节点
~List(void){
for(;m_head;m_head=m_head->m_next)
delete m_head;
}
//追加功能的实现
void append(int data){
Node* node=new Node(data);
//如果有尾节点,则让当前尾节点指向新节点
if(m_tail)
m_tail->m_next=node;
//如果没有尾节点,说明这是第一个节点
else
m_head=node;
//无论是哪种情况,新节点都是尾节点
m_tail=node;
/*另外一种实现方法
//如果头节点为空,说明这是每一个节点,也是最后一个节点
if(m_head==NULL){
m_head=node;
m_tail=node;
}
//如果头节点不为空,追加节点为尾节点
else{
m_tail->m_next=node;
m_tail=node;
}
*/
}
//在index之后插入数据功能的实现
void insert(size_t index,int data){
//从头节点向后开始遍历
for(Node *find=m_head;find;find=m_head->m_next){
//对index进行自减,当index为0时,即找到了对应元素
if(index--==0){
Node *node=new Node(data,find->m_next);
find->m_next=node;
if(find==m_tail)
m_tail=node;
return ;
}
}
//如果找不到则抛异常
throw OverBound();
}
//删除指定位置的节点的实现
void erase(size_t index){
//当index为0时,删除头节点
if(index==0){
Node *tmp=m_head;
delete m_head;
m_head=tmp->m_next;
return;
}
//定义一个临时节点用于保存要删除节点的前一个节点,以便将其m_next指针指向删除节点的m_next指向地址。
Node *findpre;
for(Node *find=m_head;find;find=m_head->m_next){
if(index==1)
findpre=find;;//将find的前一个节点的值取出来
if(index==0){
findpre->m_next=find->m_next;
//如果删除的是最后一个节点时,对尾节点重新赋值
if(find->m_next==NULL)
m_tail=findpre;
delete find;
return;
}
index--;
}
throw OverBound();
}
//获得链表的长度
int getlength(){
m_length=0;
for(Node *find=m_head;find;find=find->m_next)
m_length++;
cout<<"length is:"<<m_length<<endl;
return m_length;
}
//正向打印
void forward(void){
for(Node* find=m_head;find;find=find->m_next)
cout<<find->m_data<<' ';
cout<<endl;
}
//反向打印,调用后面的递归函数来实现
void rprint(void)const{
rprint(m_head);
cout<<endl;
}
//反向打印,数组来实现
void backward(){
size_t len=getlength();
int i;
int a[len];
Node *node=m_head;
for(i=0;i<len;i++){
a[i]=node->m_data;
node=node->m_next;
}
for(i=len-1;i>=0;i--){
cout<<a[i]<<' ';
}
cout<<endl;
}
//反向打印,通过栈来实现
void Listpop(){
for(Node *node=m_head;node;node=node->m_next)
push(node->m_data);
for(Node *node=m_head;node;node=node->m_next)
cout<<pop()<<' ';
cout<<endl;
}
//调用逆转
void reverse(){
reverse(m_head);
}
private:
//定义一个内部节点类
class Node{
public:
Node(int data=0,Node *next=NULL):m_data(data),m_next(next){}
int m_data;//数据
Node *m_next; //下一个节点的指针
};
//定义一个内部异常类
class OverBound:public exception{
const char* what()throw(){
return "链表越界!";
}
};
//反向打印以head为首的子链表,采用递归来实现
void rprint(Node *head)const{
if(head){
rprint(head->m_next);
cout<<head->m_data<<' ';
}
}
//链表的逆转功能实现
void reverse(Node *head)
{
//定义三个节点类型指针分别指向三个连续的节点,然后通过一个循环来遍历每个节点并掉转m_next的指向
Node *p, *s, *t;
p = head;
s = p->m_next;
//逆转后,头节点即为尾节点
p->m_next=NULL;
//在循环内实现每个节点的逆转
while(s->m_next!=NULL)
{
t = s->m_next;
s->m_next = p;
p = s;
s = t;
}
s->m_next = p;
m_tail=head;
m_head=s;
}
//链表数据成员
Node *m_head;//链表头指针
Node *m_tail;//链表尾指针
size_t m_length;//链表长度
};
int main(){
List l;
l.append(3);
l.append(2);
l.append(4);
l.insert(0,8);
l.insert(1,10);
l.insert(1,9);
l.append(5);
l.append(6);
l.forward();
l.erase(0);
l.erase(1);
l.forward();
l.append(7);
l.forward();
cout<<"rprint"<<endl;
l.rprint();
//l.getlength();
l.append(8);
l.append(9);
l.forward();
cout<<"backwark"<<endl;
l.backward();
l.forward();
cout<<"Listpop"<<endl;
l.Listpop();
l.reverse();
cout<<"reverse:"<<endl;
l.forward();
}