当前位置:   article > 正文

链表操作详解(C++)_c++链表用法

c++链表用法

1.结构体

struct Node
{
    int Data;
    Node * next;
};
  • 1
  • 2
  • 3
  • 4
  • 5

2.链表头部插入

Node * Insert_head(Node * & head, int value)
{
    Node * p = new Node;
    p->data = value;

    if(head == NULL)
    {
        head = p;
        head->next = NULL;
    }
    else
    {
        p->next = head;
        head = p;
    }
    return head;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3.链表尾部插入

Node * Insert_End(Node * & head, int value)
{
    Node * q = head;
    Node * p = new Node;
    p->data = value;

    if(head == NULL)
    {
        head = p;
        head->next = NULL;
    }
    else 
    {
        while(q->next != NULL)
        {
            q = q->next;
        }
        q->next = p;
    }
    return head;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.链表打印

void PrintList(Node * head)
{
    Node * p = head;

    while(p!=NULL)
    {
        cout << p->data << endl;
        p=p->next;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

5.获取链表长度

int GetLength(Node * head)
{
    Node * p = head;

    int len = 0;

    while(p != NULL)
    {
        p = p->next;
        len++;
    }

    return len;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

6.链表插入


Node * Insert(Node *& head, int value)
{
    Node * p0, *p1, *p2;

    p0 = new Node;
    p0->data = value;

    p1 = head;

    if(head == NULL)
    {
        head = p0;
        head->next = NULL;

        return head;
    }

    //找到插入的位置
    while(p0->data > p1->data && p1->next != NULL)
    {
        p2 = p1;
        p1 = p1->next;
    }

    if(p0->data <= p1->data)
    {
        if(p1 == head)
        {
            //头部插入
            p0->next = head;
            head = p0;
        }
        else
        {   
            //中间插入
            p2->next = p0;
            p0->next = p1;
        }
    }
    else
    {
        //尾部插入
        p1->next = p0;
        p0->next = NULL;
    }

    return head;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

7.链表删除

Node * Delete(Node * head, int value)
{
    Node * p, *q;

    p = head;

    while(p->data != value && p->next != NULL)
    {
        q = p;
        p = p->next;
    }

    if(p->data == value)
    {
        if(p == head)
        {
            head = p->next;
            delete p;
        }
        else
        {
            q->next = p->next;
            delete p;
        }
    }   
    else
    {
        cout << "not find data" << endl;
    }

    return head;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

8.链表清空

void Destruct(Node * head)
{
    Node *p, *q;
    
    p = head;
    q = NULL;

    while(p!=NULL)
    {
        q = p;
        p = p->next;

        delete q;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

9.链表逆序(循环方法)

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指向第三个节点

        p = q;       //执行之后p指向第二个节点   
        q = r;       //之后p指向第二个节点
    }

    head->next = NULL; //最后原来的链头变为链尾
    head = p;        //原来的链尾变成链头
    
    return head;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

10.链表逆序(递归方法)

将链表分为当前表头节点和其余节点,递归的思想就是,先将当前的表头节点从链表中拆出来,然后对剩余的节点进行逆序,最后将当前的表头节点连接到新链表的尾部,这里边的关键点是头节点head的下一个节点head->next将是逆序后的新链表的尾节点,也就是说,被摘除的头接点head需要被连接到head->next才能完成整个链表的逆序


Node * ReverseList1(Node * head)
{
    if(head == NULL || head->next == NULL)
    {
        return head;
    }

    Node* list = ReverseList1(head->next);
	
	// 将当前节点的下一个节点的指针指向当前节点,实现逆转
    head->next->next = head;
    head->next = NULL;

    return list ;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

11.两个链表有序合并后依然有序(循环方法)

Node * Merge(Node * head1, Node * head2)
{
    Node * head = NULL;

    if(head1 == NULL)
    {
        return head2;
    }

    if(head2 == NULL)
    {
        return head1;
    }

    if(head1->data <= head2->data)
    {
        head = head1;
        head1 = head1->next;
    }
    else
    {
        head = head2;
        head2 = head2->next;
    }

    Node * temp = head;

    while(head1 != NULL && head2 != NULL)
    {
        if(head1->data <= head2->data)
        {
            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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

12.两个链表有序合并后依然有序(递归方法)


Node * MergeRecursive(Node * head1, Node * head2)
{
    Node * head = NULL;

    if(head1 == NULL)
    {   
        return head2;
    }

    if(head2 == NULL)
    {
        return head1;
    }

    if(head1->data < head2->data)
    {
        head = head1;
        head->next = MergeRecursive(head1->next, head2);
    }
    else
    {
        head = head2;
        head->next = MergeRecursive(head1, head2->next);
    }

    return head;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

13.判断一个链表是否有环

bool ExitLoop(Node * head)
{
    Node * Fast = head;
    Node * Slow = head;

    while(Fast != NULL && Fast->next != NULL)
    {
        Fast = Fast->next->next;
        Slow = Slow->next;

        if(Fast == Slow)
        {
            return true;
        }
    }

    return false;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

14.找到环的入口点

从链表起点head开始到入口点的距离,与从slow和fast的相遇点到入口点的距离相等

Node * FindLoopStart(Node * head)
{
    Node * Fast = head;
    Node * Slow = head;

    while(Fast != NULL && Fast->next != NULL)
    {
        Fast = Fast->next->next;
        Slow = Slow->next;

        if(Fast == Slow)
        {
            break;
        }
    }

    if(Fast == NULL || Fast->next == NULL)
    {
        return NULL;
    }

    Node * p1 = head;
    Node * p2 = Slow;

    while(p1 != p2)
    {
        p1 = p1->next;
        p2 = p2->next;
    }

    return p1;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

15.环上节点个数

slow和fast的相遇后,Slow再走一圈就是环的长度

int GetLoopLength(Node * head)
{
    Node * Fast = head;
    Node * Slow = head;

    while(Fast != NULL && Fast->next != NULL)
    {
        Fast = Fast->next->next;
        Slow = Slow->next;

        if(Fast == Slow)
        {
            break;
        }
    }

    if(Fast == NULL || Fast->next == NULL)
    {
        return 0;
    }

    Node * p = Slow->next;
    int len = 1;

    while(p != Slow)
    {
        p = p->next;
        len++;
    }

    return len;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

16.判断两个链表是否相交并找出交点

Node * Find_Node(Node * head1, Node * head2)
{
    if(head1 == NULL || head2 == NULL)
    {
        return NULL;
    }

    Node * p1 = head1;
    Node * p2 = head2;

    int len1 = 0;
    int len2 = 0;

    while(p1->next != NULL)
    {
        len1++;
        p1 = p1->next;
    }

    while(p2->next != NULL)
    {
        len2++;
        p2 = p2->next;
    }

    //不相交
    if(p1 != p2)
    {
        return NULL;
    }

    int diff = abs(len1 - len2);

    if(len1 > len2)
    {
        p1 = head1;
        p2 = head2;
    }
    else
    {
        p1 = head2;
        p2 = head1;
    }

    for(int i=0; i<diff; i++)
    {
        p1 = p1->next;
    }

    while(p1 != p2)
    {
        p1 = p1->next;
        p2 = p2->next;
    }
    
    return p1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
在双指针遍历的过程中,如果一个指针达到链表末尾后,将其重定向到另一个链表的头部,
这就保证了两个指针在相遇点相遇。这个方法不受链表长度差异的影响。
Node * getIntersectionNode(Node* head1, Node* head2)
{
  if (head1 == NULL || head2 == NULL) {
    return NULL;
  }

  Node* p1 = head1;
  Node* p2 = head2;

  while (p1 != p2)
  {
    p1 = p1==NULL? p2:p1->next;
    p2 = p2==NULL? p1:p2->next;
  }
  
  return p1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/278064
推荐阅读
相关标签
  

闽ICP备14008679号