当前位置:   article > 正文

数据结构经典面试之链表——C#和C++篇_链表 c++

链表 c++


在这里插入图片描述

链表是一种常见的基础数据结构,它由一系列节点组成,每个节点包含数据域和指向下一个节点的指针。链表与数组不同,它不要求节点在内存中连续存储,这使得链表在插入和删除操作时具有较高的效率。

本文将介绍链表的基本概念、操作以及在C#和C++语言中的实现。

一、链表的基本概念

节点(Node)
节点是链表的基本单元,它包含两个部分:数据域和指针域。数据域用于存储节点的数据,指针域用于存储下一个节点的地址。

单链表(Singly Linked List)
单链表是一种每个节点只有一个指针指向下一个节点的链表。它是链表的最基本形式。

双向链表(Doubly Linked List)
双向链表是一种每个节点有两个指针,一个指向前一个节点,另一个指向下一个节点的链表。这使得双向链表可以方便地访问节点的前驱和后继。

循环链表(Circular Linked List)
循环链表是一种最后一个节点的指针指向第一个节点的链表。这使得循环链表在末尾追加节点时更为方便。

二、链表的操作

  • 插入操作

插入操作包括在链表的头部、中间和尾部插入节点。

(1)在链表头部插入节点

在链表头部插入节点时,新节点的指针指向原头节点,然后将新节点设置为头节点。

(2)在链表中间插入节点

在链表中间插入节点时,需要找到插入位置的前一个节点,将新节点的指针指向原中间节点,然后将原中间节点的指针指向新节点。

(3)在链表尾部插入节点

在链表尾部插入节点时,需要找到链表的最后一个节点,将最后一个节点的指针指向新节点,然后将新节点设置为最后一个节点。

  • 删除操作

删除操作包括删除链表的头部、中间和尾部节点。

(1)删除链表头部节点

删除链表头部节点时,需要将头节点的指针指向下一个节点,然后将原头节点从链表中释放。

(2)删除链表中间节点

删除链表中间节点时,需要找到删除节点的前一个节点,将前一个节点的指针指向删除节点的下一个节点。

(3)删除链表尾部节点

删除链表尾部节点时,需要找到链表的最后一个节点的前一个节点,将最后一个节点的前一个节点的指针指向null。

三、定义链表的节点结构体(C#)

在C#中,我们首先定义链表的节点结构体,它包含数据域和指向下一个节点的指针。

public struct Node
{
    public int Data { get; set; }
    public Node Next { get; set; }

    public Node(int data)
    {
        Data = data;
        Next = null;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

四、定义链表的基本操作类(C#)

在C#中,我们定义一个链表类,包含基本操作方法,如插入、删除等。

public class LinkedList
{
    public Node Head { get; set; }

    public void InsertAtHead(int data)
    {
        var newNode = new Node(data);
        newNode.Next = Head;
        Head = newNode;
    }

    public void InsertAtTail(int data)
    {
        var newNode = new Node(data);
        if (Head == null)
        {
            Head = newNode;
            return;
        }

        var current = Head;
        while (current.Next != null)
        {
            current = current.Next;
        }

        current.Next = newNode;
    }

    public void DeleteAtHead()
    {
        if (Head == null)
        {
            return;
        }

        Head = Head.Next;
    }

    public void DeleteAtTail()
    {
        if (Head == null)
        {
            return;
        }

        if (Head.Next == null)
        {
            Head = null;
            return;
        }

        var current = Head;
        while (current.Next.Next != null)
        {
            current = current.Next;
        }

        current.Next = null;
    }
}
  • 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
  • 58
  • 59
  • 60
  • 61

五、创建一个链表实例并进行基本操作演示(C#)

下面我们创建一个链表实例,并演示如何进行基本操作。

public class Program
{
    public static void Main(string[] args)
    {
        LinkedList linkedList = new LinkedList();

        linkedList.InsertAtHead(1);
        linkedList.InsertAtHead(2);
        linkedList.InsertAtHead(3);
        linkedList.InsertAtTail(4);

        linkedList.DeleteAtHead();
        linkedList.DeleteAtTail();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

六、编写一个自定义链表操作函数(C++)

在C++中,我们首先定义链表的节点结构体,然后编写一个自定义链表操作函数,用于创建和打印链表。

#include <iostream>

struct Node
{
    int data;
    Node *next;

    Node(int data) : data(data), next(nullptr) {}
};

void printList(Node *head)
{
    Node *current = head;
    while (current != nullptr)
    {
        std::cout << current->data << " -> ";
        current = current->next;
    }
    std::cout << "null" << std::endl;
}

Node* createList(int arr[], int n) {
    Node* dummy = new Node(0);
    Node* tail = dummy;
    for (int i = 0; i < n; ++i) {
        Node* newNode = new Node(arr[i]);
        tail->next = newNode;
        tail = newNode;
    }
    return dummy->next;
}
  • 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

七、在C++中演示创建和操作一个链表实例(C++)

下面我们在C++中演示如何创建和操作一个链表实例。

int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);

    Node* head = createList(arr, n);
    printList(head);

    // 删除链表的第一个节点
    Node* temp = head;
    head = head->next;
    delete temp;

    // 插入一个新节点到链表尾部
    Node* newNode = new Node(6);
    newNode->next = nullptr;
    temp = head;
    while (temp->next != nullptr)
    {
        temp = temp->next;
    }
    temp->next = newNode;

    printList(head);

    return 0;
}
  • 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

八、总结并对比C#和C++实现链表数据结构的不同点

在C#中,我们使用结构体Node和类LinkedList来实现链表。C#是一种强类型语言,它提供了自动垃圾回收机制,这使得内存管理相对简单。在C#中,我们通过属性来访问和设置节点的Data和Next字段。

在C++中,我们使用结构体Node来实现链表节点,并使用指针来访问和设置节点的data和next字段。C++是一种静态类型语言,它不提供自动垃圾回收,因此我们需要手动管理内存,例如使用new和delete操作符。

在C#中,我们直接在LinkedList类中提供了基本操作方法,如InsertAtHead、InsertAtTail、DeleteAtHead和DeleteAtTail。而在C++中,我们定义了一个createList函数来创建链表,并使用printList函数来打印链表。

总结

总的来说,C#和C++实现链表的方式有一些不同,主要体现在内存管理、类型系统和编程习惯上。然而,无论是C#还是C++,链表的核心概念和基本操作都是相似的。通过理解和掌握链表的数据结构,我们可以更加高效地处理数据和优化程序性能。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/756237
推荐阅读
相关标签
  

闽ICP备14008679号