01-(2)数据结构- 一步一步写算法(之循环单向链表)

   前面的博客中,我们曾经有一篇专门讲到单向链表的内容。那么今天讨论的链表和上次讨论的链表有什么不同呢?重点就在这个"循环"上面。有了循环,意味着我们可以从任何一个链表节点开始工作,可以把root定在任何链表节点上面,可以从任意一个链表节点访问数据,这就是循环的优势。
    那么在实现过程中,循环单向链表有什么不同?
    1)打印链表数据
[cpp] view plain copy
void print_data(const LINK_NODE* pLinkNode)
{
    LINK_NODE* pIndex = NULL;
    if(NULL == pLinkNode)
        return;  

    printf("%d\n", pLinkNode->data);
    pIndex = pLinkNode->next;
    while(pLinkNode != pIndex){
        printf("%d\n", pIndex->data);
        pIndex = pIndex ->next;
    }
}
    以往,我们发现打印数据的结束都是判断指针是否为NULL,这里因为是循环链表所以发生了变化。原来的条件(NULL != pLinkNode)也修改成了这里的(pLinkNode != pIndex)。同样需要修改的函数还有find函数、count统计函数。

    2)插入数据
[cpp] view plain copy
STATUS insert_data(LINK_NODE** ppLinkNode, int data)
{
    LINK_NODE* pNode;
    if(NULL == ppLinkNode)
        return FALSE;  

    if(NULL == *ppLinkNode){
        pNode = create_link_node(data);
        assert(NULL != pNode);  

        pNode->next = pNode;
        *ppLinkNode = pNode;
        return TRUE;
    }  

    if(NULL != find_data(*ppLinkNode, data))
        return FALSE;  

    pNode = create_link_node(data);
    assert(NULL != pNode);  

    pNode->next = (*ppLinkNode)->next;
    (*ppLinkNode)->next = pNode;
    return TRUE;
}
这里的insert函数在两个地方发生了变化:
    a)如果原来链表中没有节点,那么链表节点需要自己指向自己
    b)如果链表节点原来存在,那么只需要在当前的链表节点后面添加一个数据,同时修改两个方向的指针即可

    3) 删除数据
[cpp] view plain copy
STATUS delete_data(LINK_NODE** ppLinkNode, int data)
{
    LINK_NODE* pIndex = NULL;
    LINK_NODE* prev = NULL;
    if(NULL == ppLinkNode || NULL == *ppLinkNode)
        return FALSE;  

    pIndex = find_data(*ppLinkNode, data);
    if(NULL == pIndex)
        return FALSE;  

    if(pIndex == *ppLinkNode){
        if(pIndex == pIndex->next){
            *ppLinkNode = NULL;
        }else{
            prev = pIndex->next;
            while(pIndex != prev->next)
                prev = prev->next;  

            prev->next = pIndex->next;
            *ppLinkNode = pIndex->next;
        }
    }else{
        prev = pIndex->next;
        while(pIndex != prev->next)
            prev = prev->next;
        prev->next = pIndex->next;
    }  

    free(pIndex);
    return TRUE;
}
和添加数据一样,删除数据也要在两个方面做出改变:
    a)如果当前链表节点中只剩下一个数据的时候,删除后需要设置为NULL
    b)删除数据的时候首先需要当前数据的前一个数据,这个时候就可以从当前删除的数据开始进行遍历
    c) 删除的时候需要重点判断删除的数据是不是链表的头结点数据
时间: 2024-10-09 23:53:02

01-(2)数据结构- 一步一步写算法(之循环单向链表)的相关文章

一步一步写算法(之单向链表)

原文:一步一步写算法(之单向链表) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 有的时候,处于内存中的数据并不是连续的.那么这时候,我们就需要在数据结构中添加一个属性,这个属性会记录下面一个数据的地址.有了这个地址之后,所有的数据就像一条链子一样串起来了,那么这个地址属性就起到了穿线连结的作用. 相比较普通的线性结构,链表结构的优势是什么呢?我们可以总结一下: (1)单个节点创建非常方便,普通的线性内存通常在创建的时候就需要设定数据的

01-(2)数据结构- 一步一步写算法(之单向链表)

有的时候,处于内存中的数据并不是连续的.那么这时候,我们就需要在数据结构中添加一个属性,这个属性会记录下面一个数据的地址.有了这个地址之后,所有的数据就像一条链子一样串起来了,那么这个地址属性就起到了穿线连结的作用. 相比较普通的线性结构,链表结构的优势是什么呢?我们可以总结一下: (1)单个节点创建非常方便,普通的线性内存通常在创建的时候就需要设定数据的大小 (2)节点的删除非常方便,不需要像线性结构那样移动剩下的数据 (3)节点的访问方便,可以通过循环或者递归的方法访问到任意数据,但是平均的

一步一步写算法(之循环单向链表)

原文:一步一步写算法(之循环单向链表) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面的博客中,我们曾经有一篇专门讲到单向链表的内容.那么今天讨论的链表和上次讨论的链表有什么不同呢?重点就在这个"循环"上面.有了循环,意味着我们可以从任何一个链表节点开始工作,可以把root定在任何链表节点上面,可以从任意一个链表节点访问数据,这就是循环的优势. 那么在实现过程中,循环单向链表有什么不同? 1)打印链表数据 void pri

数据结构之自建算法库——循环双链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时循环链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:cdlinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CDLINKLIST_H_INCLUDED #define CDLINKLIST_H_INCLUDED //循环双链表基本运算函数 typedef int E

数据结构之自建算法库——循环单链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时双链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:clinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CLINKLIST_H_INCLUDED #define CLINKLIST_H_INCLUDED //循环单链表基本运算函数 typedef int ElemT

学点PYTHON基础的东东--数据结构,算法,设计模式---单向链表

看来看来,还是以下这个实现最优雅.. 其它的,要么NODE冗余,要么初始化丑陋... #!/usr/bin/env python # -*- coding: utf-8 -*- class Node: def __init__(self, initdata): self.__data = initdata self.__next = None def getData(self): return self.__data def getNext(self): return self.__next d

一步一步写算法(之 算法总结)

原文:一步一步写算法(之 算法总结) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 自10月初编写算法系列的博客以来,陆陆续续以来写了几十篇.按照计划,还有三个部分的内容没有介绍,主要是(Dijkstra算法.二叉平衡树.红黑树).这部分会在后面的博客补充完整.这里主要是做一个总结,有兴趣的朋友可以好好看看,欢迎大家提出宝贵意见. (1) 排序算法 快速排序 合并排序 堆排序 选择排序 基数排序 冒泡排序 插入排序 希尔排序 链表排序

一步一步写算法(之双向链表)

原文:一步一步写算法(之双向链表) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面的博客我们介绍了单向链表.那么我们今天介绍的双向链表,顾名思义,就是数据本身具备了左边和右边的双向指针.双向链表相比较单向链表,主要有下面几个特点: (1)在数据结构中具有双向指针 (2)插入数据的时候需要考虑前后的方向的操作 (3)同样,删除数据的是有也需要考虑前后方向的操作 那么,一个非循环的双向链表操作应该是怎么样的呢?我们可以自己尝试一下: (

《转载》一步一步写算法(之 算法总结)

自10月初编写算法系列的博客以来,陆陆续续以来写了几十篇.按照计划,还有三个部分的内容没有介绍,主要是(Dijkstra算法.二叉平衡树.红黑树).这部分会在后面的博客补充完整.这里主要是做一个总结,有兴趣的朋友可以好好看看,欢迎大家提出宝贵意见. (1) 排序算法 快速排序 合并排序 堆排序 选择排序 基数排序 冒泡排序 插入排序 希尔排序 链表排序 (2) 数据结构 线性队列 线性堆栈 单向链表 双向链表 循环单向链表 排序二叉树(插入,删除上.中.下.保存和加载) 哈希表 哈希二叉树  红