c++实现链表的添加删除节点,打印链表,从尾到头打印链表

链表c++添加删除节点,打印链表

链表是一种动态数据结构。因为在创建链表时,无须知道链表的长度。当插入一个节点时,我们只需要为新节点分配内存,然后调整指针的指向来确保新节点被链接到链表当中。内存分配不是在创建链表时一次性完成的,而是每添加一个节点分配一次内存。由于没有闲置内存,链表的空间效率比数组高。

代码如下:

#include<bits/stdc++.h>
using namespace std;
//单项链表的定义如下:
struct ListNode{
 int value;
 ListNode* NextNode;
};
//往链表末尾添加一个节点的代码如下:
void AddNode(ListNode* head,int value)
{
 ListNode* temp=new ListNode;
 temp->value=value ;
 temp->NextNode=NULL;
 if(head==NULL)
 {
  head=temp;
 }
 else{
  ListNode* tempNode=head;
  while(tempNode->NextNode!=NULL)
  {
   tempNode=tempNode->NextNode;
  }
  
  tempNode->NextNode=temp;
 }
}
//如果想在链表中找到值为value的节点只能从头节点开始。
//沿着指向下一个节点的指针遍历链表,他的时间效率为O(n).
//下面是在链表中找到第一个含有某值的节点并删除该节点的代码
ListNode* RemoveNode(ListNode* head , int value)
{
 ListNode* toRemoveNode=NULL;
 if(head==NULL)return NULL;
 if(head->value==value)
 {
  toRemoveNode=head;
  
  head=head->NextNode; 
 }
 else{
   ListNode* temp=head;
   while(temp->NextNode!=NULL&&temp->NextNode->value!=value)
   {
    temp=temp->NextNode;
   }
   if(temp->NextNode!=NULL&&temp->NextNode->value==value)
   {
    toRemoveNode=temp->NextNode;
    temp->NextNode=temp->NextNode->NextNode;
   }
 }
 if(toRemoveNode!=NULL)
 {
 
  delete toRemoveNode;
  toRemoveNode=NULL;
 }
  return head;
}
//正常打印代码
void print(ListNode* head)
{
 if(head==NULL)return;
 
 ListNode* temp=head;
 while(temp!=NULL)
 {
  cout<<temp->value<<" ";
  temp=temp->NextNode;
  
 }
 cout<<endl;
}
//从尾到头打印链表1
//第一个遍历到的节点最后一个输出,这就是典型的“后进先出的思想”,我们可以用栈实现这种顺序
//每经过一个节点就把该节点加入栈中。当遍历完链表后,再从栈顶开始逐个输出节点的值。
//此时节点顺序已经反转了。这种思路代码实现如下
void PrintNode_Iteratively_stack(ListNode* head)//基于栈的实现 
{
 stack<ListNode*> nodes;
 ListNode* node=head;
 while(node!=NULL)
 {
  nodes.push(node);
  node=node->NextNode;
 }
 while(!nodes.empty())
 {
  node=nodes.top();
  cout<<node->value<<" ";
  nodes.pop();
 }
 cout<<endl;
}
//从尾到头打印链表1
//既然想到了用栈实现这个函数,而递归本质就是一个栈结构,于是很自然的又想到用递归实现
//每访问一个节点的时候,先递归输出它后面的节点,再输出自身节点。
void PrintNode_Iteratively_dfs(ListNode* head)
{
 if(head!=NULL)
 {
  if(head->NextNode!=NULL)
  {
   PrintNode_Iteratively_dfs(head->NextNode);
  } 
  cout<<head->value<<" ";
 }
 //cout<<endl;
}
//上面基于递归的代码看起来很简洁,但有一个问题:
//当链表很长的时候,就会导致函数调用层级很深,从而导致函数栈溢出。
//显然用栈基于循环实现的代码鲁棒性更好一些
int main()
{ 
 ListNode* head=new ListNode;
 head->value=-1;
 head->NextNode=NULL;
 //创建head节点 

 for(int i=0;i<10;i++)
 AddNode(head,i);
 //添加节点 
 
 print(head);
 head=RemoveNode(head,2);
 print(head);
 head=RemoveNode(head,-1);
 print(head);
 head=RemoveNode(head,9);
 print(head);
 
 PrintNode_Iteratively_stack(head);
 
 PrintNode_Iteratively_dfs(head); 
 delete head;
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值