C++链表基本操作

 

 
#include <iostream.h>
#include < string .h>

struct Node
{
   
int num ;
    Node *next ;
};

Node* Create()   
// 链表创建
{
   
int n= 0 ;
    Node *p1,*p2,*head;
    p1=p2=
new Node;
    cin>>p1->num;
    head=NULL;
   
while (p1->num!= 0 )
    {
       
if (n== 1 )
        {
            head=p1;
        }
       
else
         p2->next=p1;
        p2=p1;
        p1=
new Node;
        cin>>p1->num;
        n++;
    }
    p2->next=NULL;

   
return head;
}

 
 
 
 
 
 
 
int ListLength(Node L) // 链表的计数
{  
Node p=L;
   int count=0;
   while (p->next)
   {
     count++;
     p=p->next;
   }
   return count;
}
 
int Search(Node &L , int value)    // 链表的查找
{    
Node p=L;
   int index=0;
   while (p)
   {
if(p->num== value)
return index;
     p=p->next;
        index++;
   }
      return 0;
}
 
void Print(Node *head) // 输出链表
{
       Node* p=head;
   
while (p)
    {
        cout<<p->num<<
" " ;
        p=p->next;
    }
    cout<<endl;

}

 
 
 
 
 
 
void Destruct(Node *head)   // 清空链表
{
    Node *current = head, *temp = NULL;
   while (current)
    {
        temp = current;
        current = current ->next;
        delete temp;
    }
}
 
 
 
 
 
Node *ReverseList(Node *head)    // 链表逆序(循环方法)
{  
  Node *p,*q,*r;  
 p=head;               // 一开始 p 指向第一个节点   
 q=p->next;           //q 指向第二个节点   
 while (q!=NULL)     // 如果没到链尾   
 {                      // 以第一次循环为例   
 r=q->next;           //r 暂时存储第三个节点   
 q->next=p;           // 没执行此句前, q->next 指向第三个节点   
                         // 执行之后, q->next 指向第一个节点 p  
 p=q;                   // 之后 p 指向第二个节点   
 q=r;                   //q 指向第三个节点   
                         // ...p=>q=>r... 变为    ...p<=q<=r...  
 }  
 head->next=NULL;   // 最后原来的链头变为链尾,把它指向 NULL   
 head=p;               // 原来的链尾变成链头   
 return   head;  
 }
 
 
 
 
 
 
 
 
 
 
 
Node *ReverseList2(Node *head)   // 链表逆序(递归方法)
 

{
    if (!head)
    {
        return NULL;
    }

    Node *temp = ReverseList2 (head->next);

    if (!temp)
    {
        return head;
    }

    head->next->next = head;
    head->next = NULL;

    return temp;
}
递归时 ,head 可以分别用 head head1,head2 ...headn-1, headn 来表示总共 n+1 个节点
temp = ReverseList2( head->next ); 此句的递归一直将参数传进来的。
Node* head 递归到 headn 然后判断下列语句:
else if( !headn->next )
{
return headn;
}
将返回值传给 temp, 此时 temp 指向链尾 , 由于在此次返回 , 故此次没有执行最后的 else 的那部分的语句 , 返回上一级即是 headn-1 那一级 , 继续执行
下面的 headn-1->next->next = headn-1;
       headn-1->next = NULL; // 此两句将最后两个逆序连接 ,
       return temp;
// 之后返回 temp 比上一层的 temp 即是执行 temp = ReverseList2( head->next ) 赋值 , 因为递归的口都是在这里的 , 如果说好理解点也可以将 temp 来编号
同理
  在返回 temp , 继续执行
     headn-2->next->next = headn-2;
     headn-2->next = NULL;
     return temp;
 .....
一直到 head 即是原链表的第一个节点 , 在对其 head->next = NULL , 此时以 temp 所指向的节点为链头的逆序链表就形成了 .
 
 
// 已知两个链表 head1 head2 各自有序,请把它们合并成一个链表依然有序。(循环方法)
//(
保留所有结点,即便大小相同)
Node *Merge(Node *head1 , Node *head2)
{
   
if ( head1 == NULL)
       
return head2 ;
   
if ( head2 == NULL)
       
return head1 ;
   
   
if ( head1->num < =head2->num )
    {
        head = head1 ;
        head1= head1->next;
     }
   
else
    {
        head = head2 ;
        head2 = head2->next ;
    }
    Node *temp = head ;
   
while ( head1 != NULL && head2 != NULL)
    {
       
if ( head1->num <= head2->num )
        {
            temp->next = head1 ;
           head1 = head1->next ;
temp =temp->next;
        }
       
else
        {
            temp->next = head2;
          head2 = head2->next ;
temp =temp->next;
        }
    }
   
if (head1 == NULL) temp->next = head2;
   
if (head2 == NULL) temp->next = head1;
   
return head;
}

 
 
 
 
// 已知两个链表 head1 head2 各自有序,请把它们合并成一个链表依然有序。(递归方法)
Node *MergeRecursive(Node * head1 , Node * head2 )
{
   
if ( head1 == NULL )
       
return head2 ;
   
if ( head2 == NULL)
       
return head1 ;
    Node *head = NULL ;
   
if ( head1->num < head2->num )
    {
        head = head1 ;
        head->next = MergeRecursive(
head1->next ,head2);
    }
   
else
    {
        head = head2 ;
        head->next = MergeRecursive(head1,
head2->next );
    }
   
return head ;
}

从递归函数的定义不难看出,这个函数定义中递归调用时形参发生改变,即是当前节点的下一个节点,每一次递归都按照这个规律逐次遍历两个有序链表的每一个节点,判断大小后使 head 指向数据域较小的节点,由堆栈空间的思想可知递归到最后指向 NULL 时才返回两个链表的某一个头节点,而此时 head->next=head2 head=head1 链表的最后一个节点,该语句就使得这样一个指向关系确立起来。
以上均通过理想的有序链表,即链表 1 的任何一个数据值都小于链表 2 来做分析,其他的情况讨论方式类似。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Node* Delete(Node* head , int num) // 删除节点
{
   
if (head==NULL)
    {
        cout<<
"List is Null" <<endl;
       
return head;
    }
    Node *p1,*p2;
    p1=head;
   
while (p1->num!=num && p1->next)
    {   
        p2=p1;
        p1=p1->next;
    }
   
if (p1->num==num)
    {
       
if (p1==head)
        {
            head=p1->next;
        }
       
else
            p2->next=p1->next;
    }
   
else
        cout<<
"Do not Find The Num " <<num<<endl;
   
return head;
}

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Node* Insert(Node* head , int num) // 插入节点
{
   
    Node *p0,*p1,*p2;
    p1=head;
    p0=
new Node;
    p0->num=num;
   
if (head==NULL)
    {
        head=p0;
        p0->next=NULL;
       
return head;
    }
   
   
while (p1->num<p0->num && p1->next)
    {
        p2=p1;
        p1=p1->next;
    }
   
   
if (p1->num>=p0->num)
    {
       
if (p1==head)
            head=p0;
       
else
         p2->next=p0;
        p0->next=p1;
    }
   
else
    {
        p1->next=p0;
        p0->next=NULL;
    }
   
   
return head;
}

void main()
{ 省略不写 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值