再谈单向链表操作——单向链表的访问与修改

链表的访问

既然理解了链表的构成,对链表的访问也就不成问题了。不过要特别注意的是,对于数组,我们可以利用下标直接访问任何一个元素(这被称为“随机访问”),而对于单向链表,只能从头结点开始,依次进行“顺序访问”

假设我们已经按照前文创建了一个链表,下面我们设计一个函数,查找是否存在某数据:

//参数说明:p为头指针,n为所查找的数据
void search_node(l* p, int n) {
    //若非尾结点,则继续循环
    while(p->next != NULL) {
        //将指针指向下一个结点
        p = p->next;
        if(p->num == n) {
            printf("找到该数据!");
            return;
        }
    }
    printf("未找到该数据!");
    return;
}

尤其要注意第3行,由于我们的链表有不存储数据的头结点,要先将指针指向下一个结点,再访问数据。读者不妨想一想,如果使用无头结点的链表,指针后移的操作应该在何处进行。

结点的插入

假如我们需要将一个新结点(记为M)插入结点N后面,只需先将M的指针域指向N后面的结点(也就是N指针域所指的结点),再将N结点的指针域指向M即可。假设有一个指针p指向N结点,又有一个指向新结点M的指针p_new,那么只需进行如下操作:

p_new->next = p->next;
p->next = p_new;

特别注意,如果结点N为尾结点,那么新结点M的指针域需要指向NULL,操作如下:

p_new->next = NULL;
p->next = p_new;

下面我们设计一个函数,查找某数据并将新数据插入其后:

//参数说明:p为头指针,n为所查找的数据
void insert_node(l* p, int n) {
    l* p_new;
    while(p->next != NULL) {
        p = p->next;
        if(p->num == n) {
            //找到数据后,为新结点分配空间并输入要插入的数据
            printf("请输入要插入的数据:");
            p_new = (l*)malloc(sizeof(l));
            scanf("%d", &p_new->num);
            //若为尾结点,通过如下操作插入
            if(p->next == NULL) {
                p_new->next = NULL;
                p->next = p_new;
            }
            //若非尾结点,通过如下操作插入
            else {
                p_new->next = p->next;
                p->next = p_new;
            }
        printf("插入成功!");
        return;
        }
    }
    printf("未找到该数据!");
    return;
}

结点的删除

相对插入而言,结点的删除就是小菜一碟了。不过细细想来,似乎有一些问题——我们在找到要删除的数据时,指针p已经指向了要删除的结点,但是要进行的操作是:改变它的前一个结点(称为“前驱结点”)指针域的指向,而我们的链表是单向的,无法将指针向前移动,这该怎么办呢?

因此,我们需要使用一个指向前驱结点的指针,辅助进行删除操作。

下面我们设计一个函数,查找某数据并将其结点删除:

//参数说明:p为头指针,n为所查找的数据
void delete_node(l* p, int n) {
    l* predecessor;
    while(p->next != NULL) {
        predecessor = p;
        p = p->next;
        if(p->num == n) {
            if(p->next == NULL) {
                predecessor->next = NULL;
            } else {
                predecessor->next = p->next;
            }
            //释放要删除的结点的内存
            free(p);
            printf("删除成功!");
            return;
        }
    }
    printf("未找到该数据!");
    return;
}

特别注意,最后一定不要忘记使用free()函数释放所删除结点的内存!否则会导致内存泄漏。

总结

读完上面的例子,对链表的基本操作便理解完成了,现在,不妨回过头来,看看能否理解全部代码:

#include<cstdio>
#include<cstdlib>

typedef struct linked_list {
    int num;
    struct linked_list* next;
} l;

l* create(int n) {
    l * head, * new_node, * tail;
    int i = 0;
    head = (l*)malloc(sizeof(l));
    tail = head;
    for(i = 0; i < n; ++i) {
        new_node = (l*)malloc(sizeof(l));
        scanf("%d", &new_node->num);
        tail->next = new_node;
        tail = new_node;
    }
    tail->next = NULL;
    return head;
}

void search_node(l* p, int n) {
    while(p->next != NULL) {
        p = p->next;
        if(p->num == n) {
            printf("找到该数据!");
            return;
        }
    }
    printf("未找到该数据!");
    return;
}

void insert_node(l* p, int n) {
    l* p_new;
    while(p->next != NULL) {
        p = p->next;
        if(p->num == n) {
            printf("请输入要插入的数据:");
            p_new = (l*)malloc(sizeof(l));
            scanf("%d", &p_new->num);
            if(p->next == NULL) {
                p_new->next = NULL;
                p->next = p_new;
            } else {
                p_new->next = p->next;
                p->next = p_new;
            }
            printf("插入成功!");
            return;
        }
    }
    printf("未找到该数据!");
    return;
}

void delete_node(l* p, int n) {
    l* predecessor;
    while(p->next != NULL) {
        predecessor = p;
        p = p->next;
        if(p->num == n) {
            if(p->next == NULL) {
                predecessor->next = NULL;
            } else {
                predecessor->next = p->next;
            }
            free(p);
            printf("删除成功!");
            return;
        }
    }
    printf("未找到该数据!");
    return;
}

int main() {
    l* head_pointer;
    int n;
    printf("请输入数据个数:");
    scanf("%d", &n);
    printf("请依次输入数据:");
    head_pointer = create(n);
    /*
    下面可以调用函数进行访问和修改操作,我懒得写了
    */
    return 0;
}

原文地址:https://www.cnblogs.com/mzzx/p/10111348.html

时间: 2024-10-12 14:02:04

再谈单向链表操作——单向链表的访问与修改的相关文章

链表操作---找到链表的中点

在很多链表的算法中,常常需要找到链表的中点. 这里给出一种使用双指针,一次遍历链表就能找到链表中点的方法. 使用一个快指针,每次走两步,一个慢指针,每次走一步.等快指针走到链表底部的时候,慢指针正好走到中点. /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ ListN

10、单链表操作

单链表操作 单链表操作1 /*单链表的类型定义*/ typedef int DataType; typedef struct node { DataType data; struct node * next; }LinkNode, *LinkList; /*单链表的定位运算*/ LinkNode *Locate(LinkNode *L, int k)//????为什么此处是LinkNode *Locate()类型,表示什么意思 { LinkNode *p; int i; i= 1; p = L-

单向链表操作 原文:http://canlynet.blog.163.com/blog/static/255013652009113001041903/

/********************************************** 功能:单向链表操作(注意Head指针 需要被改变时传入的是二级指针) 日期:2009.12.29 作者:DC ***********************************************/ #include <stdio.h> #include <stdlib.h> #define OVER_FLOW -2 #define OK 0 typedef int ElemTy

C语言学习之单向链表操作

该文件为单向链表操作的一些接口:(如发现有错误的地方,及时告知,不胜感激!) list.h #ifndef  _CHAINLIST_H_ #define  _CHAINLIST_H_ typedef struct { char key[15]; char name[20]; int age; }DATATYPE_T; typedef struct Node { DATATYPE_T  data; struct Node *next; }chainListType; /* 添加节点到链表末尾 */

复习下C 链表操作(单向链表)

Object-C 作为C 的包装语言(运行时.消息机制).如果不熟悉C 的话实在玩得太肤浅. 随便深入oc 内部都会接触到C. runtime .GCD.Block.消息机制... 所有强大的功能无不用的 包装体(struct 结构体).使用GCC/Clang (可以google 下.Clang 比GCC 更优化,) 编译指令. 转换OC 为 C . 终端 使用Clang 命令参考 clang -rewrite-objc file.m 查看file.cpp 文件为编译转换的C 单向链表 创建 .

Java单向链表操作详解

转自:http://blog.csdn.net/zxman660/article/details/7786354 —————————————————————————————————————————— /* 先定义一个Node类用来存储节点的值域和指针域 * 即当前节点中的值和后面节点的方法 * 在C中就是相当与定义一个结构体类型一个数据域和指针域的方法 */ class LNode{//这个写法已经非常固定了 设置两个属性分别用set函数和get函数来得到这两个属性 private int da

数据结构和算法--3链表(单向链表、双向链表、环形单向链表和约瑟夫问题)

链表 链表是以节点的方式来存储 每个节点包含data域和next域,指向下一个节点 链表的各个节点不一定是连续存储 链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定 单向列表 最大特点是可以将物理地址上不连续的数据连接起来,通过指针来对物理地址进行操作,实现增删改查等功能. 单链表分为两种:有头链表和无头链表. 有头节点的增删改查 定义一个单链表的类: //定义一个SingleLinkedList,单链表,管理HeroNode class SingleLinkedList{ //初始

python数据结构链表之单向链表

本文和大家分享的主要是python中单向链表相关内容,一起来看看吧,希望对大家学习python有所帮助. 单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. . 表元素域elem用来存放具体的数据. . 链接域next用来存放下一个节点的位置(python中的标识) . 变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点. 节点实现 class 

Python链表操作(实现)

Python链表操作 在Python开发的面试中,我们经常会遇到关于链表操作的问题.链表作为一个非常经典的无序列表结构,也是一个开发工程师必须掌握的数据结构之一.在本文中,我将针对链表本身的数据结构特点,以及链表的一些常见操作给大家做一个深入浅出的讲解,希望本文的读者能够掌握链表的操作. 1. 什么是链表? 简单地说,链表是一种无序的列表.你可以把链表里面的数据看成是随机排列的,元素之间并没有固定的先后顺序.所以,既然是无序的,那么我们就无法像操作list对象一样简单地用index来去定位和操作