单链表常见功能的实现、以及逆转等

#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();
 

}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值