带头节点链表基础操作,简单详细(附源码)

带头节点链表基础操作,简单详细(附源码)

本篇面向的是初学者,旨在帮助他们了解数据结构中的带头结点的链表。
提供详细的过程的同时附源码,也是为了让自己的进步,共勉之。

前言

链表是一种常见的数据结构,它由节点组成,每个节点包含数据和指向 下一个节点 的指针。链表的灵活性使其在编程中应用广泛,本文将介绍如何使用C++实现链表,并提供一些链表操作的示例代码。

链表结构定义

首先,我们需要定义链表的节点结构。在这个示例中,我们使用以下结构来表示链表节点:

在这里插入图片描述

typedef struct ListNode {
    int data;//值
    struct ListNode* next; //指向下一个
} ListNode, *LinkedList;

这里的ListNode 结构包含一个整数数据成员 data 和一个指向下一个节点的指针 next。同时,我们使用 LinkedList 类型来表示整个链表,它是一个指向 链表头节点的指针

初始化链表

接下来,我们需要初始化链表。下面是一个初始化链表的函数 `initLinkedList`:

在这里插入图片描述

LinkedList initLinkedList(LinkedList& head, int numElements) {
    head = (LinkedList)malloc(sizeof(ListNode)); // 分配头节点的内存
    head->next = NULL;
    LinkedList tail = head;
    int element;
    while (numElements--) {
        LinkedList new_node;
        printf("请输入一个整数:");
        scanf("%d", &element);
        new_node = (LinkedList)malloc(sizeof(ListNode)); // 分配新节点的内存
        new_node->data = element;
        new_node->next = tail->next;//为新节点的next 赋NULL
        tail->next = new_node;// 将新节点添加到链表尾部
        tail = new_node;//指向末尾
    }
    return head;
}

此函数会初始化一个包含指定数量元素的链表。首先,它分配头节点的内存,并将头节点的 next 指针置为 NULL。然后,它循环读取用户输入的整数,并将它们插入到链表的尾部。

插入元素

链表的一个常见操作是在指定位置前或后插入元素。
我们提供了两个函数 `insertBefore` 和 `insertAfter` 来执行这两种操作:

在这里插入图片描述

插入元素在指定位置前:

void insertBefore(LinkedList& head, int value, int position) {
    LinkedList previous = head;
    while (--position && previous) {//找到要插入位置的前一个节点    注意头节点不存值 
        previous = previous->next;
    }

    if (previous == NULL) {
        cout << "无效位置";
        return;
    }

    LinkedList new_node;
    new_node = (LinkedList)malloc(sizeof(ListNode));
    new_node->data = value;
    new_node->next = previous->next;
    previous->next = new_node;
}

插入元素在指定位置后:

void insertAfter(LinkedList& head, int value, int position) {
    LinkedList current = head;
    while (position && current) {
        current = current->next;
        position--;
    }

    if (current == NULL) {
        cout << "无效位置";
        return;
    }

    LinkedList new_node;
    new_node = (LinkedList)malloc(sizeof(ListNode));  // 分配新节点的内存
    new_node->next = current->next;
    current->next = new_node; // 插入新节点
    new_node->data = value;//插入要插入的值
}

这两个函数分别在指定位置前和后插入一个新节点,注意头节点不存储数据

删除元素

在这里插入图片描述

我们也提供了一个函数 `deleteNode` 来删除链表中指定位置的元素:
void deleteNode(LinkedList& head, int position) {
    LinkedList previous = head;
    while (--position && previous) {
        previous = previous->next;
    }

    if (previous == NULL) {
        cout << "无效位置";
        return;
    }

    LinkedList toDelete = previous->next;
    previous->next = toDelete->next;
    free(toDelete); // 释放被删除节点的内存
}

这个函数会删除指定位置的节点,并释放其内存别忘了释放内存

计算链表长度

要计算链表的长度,我们可以使用 `getLength` 函数:
int getLength(LinkedList head) {
    int length = 0;
    LinkedList current = head;
    while (current->next != NULL) {
        current = current->next;
        length++;
    }
    return length;
}

这个函数从链表头节点开始遍历链表,统计节点数量。

显示链表元素

要显示链表的元素,我们可以使用 `displayLinkedList` 函数:
void displayLinkedList(LinkedList head) {
    LinkedList current = head->next;//头节点不赋值
    printf("链表内容:\n");
    while (current) {
        printf("%d\n", current->data);
        current = current->next;
    }
}

这个函数从链表头节点开始遍历链表,依次打印出每个节点的数据。

main()代码

在 `main` 函数中,我们使用上述函数演示了如何初始化链表,插入和删除元素,以及计算链表的长度。最后,我们释放了链表节点的内存。
int main() {
    LinkedList head;
    int numElements;
    printf("请输入元素数量:");
    scanf("%d", &numElements);
    initLinkedList(head, numElements);
    displayLinkedList(head);

    int value, position;
    printf("请输入要在指定位置前插入的值和位置:");
    scanf("%d %d", &value, &position);
    insertBefore(head, value, position);
    displayLinkedList(head);

    printf("请输入要在指定位置后插入的值和位置:");
    scanf("%d %d", &value, &position);
    insertAfter(head, value, position);
    displayLinkedList(head);

    printf("请输入要删除的位置:");
    scanf("%d", &position);
    deleteNode(head, position);
    displayLinkedList(head);

    cout << "链表长度: " << getLength(head);

    // 释放链表节点内存
    LinkedList current = head->next;
    while (current) {
        LinkedList temp = current;
        current = current->next;
        free(temp);
    }
    free(head);

    return 0;
}

完整代码:

#include <bits/stdc++.h>
#include <stdio.h>
using namespace std;

// 定义链表节点结构
typedef struct ListNode {
    int data;
    struct ListNode* next;
} ListNode, *LinkedList;

// 初始化链表
LinkedList initLinkedList(LinkedList& head, int numElements) {
    head = (LinkedList)malloc(sizeof(ListNode)); // 分配头节点的内存
    head->next = NULL;
    LinkedList tail = head;
    int element;
    while (numElements--) {
        LinkedList new_node;
        printf("请输入一个整数:");
        scanf("%d", &element);
        new_node = (LinkedList)malloc(sizeof(ListNode)); // 分配新节点的内存
        new_node->data = element;
        new_node->next = tail->next;//为新节点的next置为NULL 
        tail->next = new_node; // 将新节点添加到链表尾部
        tail = new_node;
    }
    return head;
}

// 显示链表元素
void displayLinkedList(LinkedList head) {
    LinkedList current = head->next;
    printf("链表内容:\n");
    while (current) {
        printf("%d\n", current->data);
        current = current->next;
    }
}

// 在指定位置前插入元素
void insertBefore(LinkedList& head, int value, int position) {
    LinkedList previous = head;
    while (--position && previous) {//找到要插入位置的前一个节点    注意头节点不存值 
        previous = previous->next;
    }

    if (previous == NULL) {
        cout << "无效位置";
        return;
    }

    LinkedList new_node;
    new_node = (LinkedList)malloc(sizeof(ListNode)); // 分配新节点的内存
    new_node->data = value;
    new_node->next = previous->next;
    previous->next = new_node; // 插入新节点
}

// 在指定位置后插入元素
void insertAfter(LinkedList& head, int value, int position) {
    LinkedList current = head;
    while (position && current) { //找的指定位置 
        current = current->next;
        position--;
    }

    if (current == NULL) {
        cout << "无效位置";
        return;
    }

    LinkedList new_node;
    new_node = (LinkedList)malloc(sizeof(ListNode)); // 分配新节点的内存
    new_node->next = current->next;
    current->next = new_node; // 插入新节点
    new_node->data = value;
}

// 删除指定位置的元素
void deleteNode(LinkedList& head, int position) {
    LinkedList previous = head;
    while (--position && previous) {
        previous = previous->next;
    }

    if (previous == NULL) {
        cout << "无效位置";
        return;
    }

    LinkedList toDelete = previous->next;
    previous->next = toDelete->next;
    free(toDelete); // 释放被删除节点的内存
}

// 计算链表的长度
int getLength(LinkedList head) {
    int length = 0;
    LinkedList current = head;
    while (current->next != NULL) {
        current = current->next;
        length++;
    }
    return length;
}

int main() {
    LinkedList head;
    int numElements;
    printf("请输入元素数量:");
    scanf("%d", &numElements);
    initLinkedList(head, numElements);
    displayLinkedList(head);

    int value, position;
    printf("请输入要在指定位置前插入的值和位置:");
    scanf("%d %d", &value, &position);
    insertBefore(head, value, position);
    displayLinkedList(head);

    printf("请输入要在指定位置后插入的值和位置:");
    scanf("%d %d", &value, &position);
    insertAfter(head, value, position);
    displayLinkedList(head);

    printf("请输入要删除的位置:");
    scanf("%d", &position);
    deleteNode(head, position);
    displayLinkedList(head);

    cout << "链表长度: " << getLength(head);

    // 释放链表节点内存
    LinkedList current = head->next;
    while (current) {
        LinkedList temp = current;
        current = current->next;
        free(temp);
    }
    free(head);

    return 0;
}

结语

这篇博客介绍了如何使用C++实现链表以及一些常见的链表操作。链表是一个重要的数据结构,它在编程中经常用于解决各种问题。希望这些示例代码能够帮助你更好地理解链表的工作原理和应用。

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
/*带头结点头文件 hlinklist.h*/ #include <stdio.h> typedef int datatype; typedef struct link_node { datatype data; struct link_node *next; }node; /*初始化链表*/ node *init() { node *head; head=(node *)malloc(sizeof(node)); head->next=0; return head; } /*尾插法创建一个带头结点链表*/ node *creat(node *head) { node *r,*s; int x; r=head; printf("在新链表中输入数据以0结束:"); scanf("%d",&x); while(x) { s=(node*)malloc(sizeof(node)); s->data=x; r->next=s; r=s; scanf("%d",&x); } r->next=0; return head; } /*打印链表的结点值*/ void print(node *head) { node *p; p=head->next; if(!p) printf("链表内容为空!"); else while(p) { printf("%5d",p->data); p=p->next; } printf("\n"); } /*在单链表中查找第i个结点的地址*/ node *find(node *head,int i) { node *p=head; int j=0; if(i<0) {printf("不存在!");return 0;} if(i==0) return head; while(p&&i!=j) { p=p->next; j++; } return p; } /*在带头结点的单链表第i个位置后插入一个数*/ node *insert(node *head,int i,datatype x) { node *p,*q; q=find(head,i); if(!q) { printf("插入的位置不存在!\n");return head;} else { p=(node *)malloc(sizeof(node)); p->data=x; p->next=q->next; q->next=p; } return head; } /*在带头结点的单链表中删除一个为x的值*/ node *dele(node *head,datatype x) { node *pre=head,*p; p=head; while(p&&p->data!=x) { pre=p;p=p->next; } if(p) { pre->next=p->next; free(p); } return head; } /*把带头结点的单链表倒置(以结点形式 )*/ node *Dao_zhi(node *head) { node *p,*s; p=head->next; head->next=NULL; while(p) { s=p; p=p->next; s->next=head->next; head->next=s; } return head; } /*删除链表中重复的结点 */ node *dele1(node *head) { node *pre,*p,*q; if(head->next==0||!head->next->next) { printf("链表为空!"); return head; } //pre=head->next; q=head->next; while(q) { pre=q; p=q->next; while(p) { while(p&&q->data!=p->data) { pre=p;p=p->next; } if(p) { pre->next=p->next; free(p); } p=pre->next; } q=q->next; } return head; }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值