有的时候,处于内存中的数据并不是连续的。那么这时候,我们就需要在数据结构中添加一个属性,这个属性会记录下面一个数据的地址。有了这个地址之后,所有的数据就像一条链子一样串起来了,那么这个地址属性就起到了穿线连结的作用。

相比较普通的线性结构,链表结构的优势是什么呢?我们可以总结一下:

(1)单个节点创建非常方便,普通的线性内存通常在创建的时候就需要设定数据的大小

(2)节点的删除非常方便,不需要像线性结构那样移动剩下的数据

(3)节点的访问方便,可以通过循环或者递归的方法访问到任意数据,但是平均的访问效率低于线性表

那么在实际应用中,链表是怎么设计的呢?我们可以以int数据类型作为基础,设计一个简单的int链表:

(1)设计链表的数据结构

typedef struct _LINK_NODE
{
int data;
struct _LINK_NODE* next;
}LINK_NODE;

(2)创建链表

LINK_NODE* alloca_node(int value)
{
LINK_NODE* pLinkNode = NULL;
pLinkNode = (LINK_NODE*)malloc(sizeof(LINK_NODE)); pLinkNode->data = value;
pLinkNode->next = NULL;
return pLinkNode;
}

(3)删除链表

void delete_node(LINK_NODE** pNode)
{
LINK_NODE** pNext;
if(NULL == pNode || NULL == *pNode)
return ; pNext = &(*pNode)->next;
free(*pNode);
delete_node(pNext);
}

(4)链表插入数据

STATUS _add_data(LINK_NODE** pNode, LINK_NODE* pDataNode)
{
if(NULL == *pNode){
*pNode = pDataNode;
return TRUE;
} return _add_data(&(*pNode)->next, pDataNode);
} STATUS add_data(const LINK_NODE** pNode, int value)
{
LINK_NODE* pDataNode;
if(NULL == *pNode)
return FALSE; pDataNode = alloca_node(value);
assert(NULL != pDataNode);
return _add_data((LINK_NODE**)pNode, pDataNode);
}

(5)删除数据

STATUS _delete_data(LINK_NODE** pNode, int value)
{
LINK_NODE* pLinkNode;
if(NULL == (*pNode)->next)
return FALSE; pLinkNode = (*pNode)->next;
if(value == pLinkNode->data){
(*pNode)->next = pLinkNode->next;
free(pLinkNode);
return TRUE;
}else{
return _delete_data(&(*pNode)->next, value);
}
} STATUS delete_data(LINK_NODE** pNode, int value)
{
LINK_NODE* pLinkNode;
if(NULL == pNode || NULL == *pNode)
return FALSE; if(value == (*pNode)->data){
pLinkNode = *pNode;
*pNode = pLinkNode->next;
free(pLinkNode);
return TRUE;
} return _delete_data(pNode, value);
}

(6)查找数据

LINK_NODE* find_data(const LINK_NODE* pLinkNode, int value)
{
if(NULL == pLinkNode)
return NULL; if(value == pLinkNode->data)
return (LINK_NODE*)pLinkNode; return find_data(pLinkNode->next, value);
}

(7)打印数据

void print_node(const LINK_NODE* pLinkNode)
{
if(pLinkNode){
printf("%d\n", pLinkNode->data);
print_node(pLinkNode->next);
}
}

(8)统计数据

int count_node(const LINK_NODE* pLinkNode)
{
if(NULL == pLinkNode)
return 0; return 1 + count_node(pLinkNode->next);
}

【预告: 下一篇博客介绍双向链表

c++(单向链表)的更多相关文章

  1. Reverse Linked List II 单向链表逆序(部分逆序)

    0 问题描述 原题点击这里. 将单向链表第m个位置到第n个位置倒序连接.例如, 原链表:1->2->3->4->5, m=2, n =4 新链表:1->4->3-& ...

  2. 【编程题目】输入一个单向链表,输出该链表中倒数第 k 个结点

    第 13 题(链表):题目:输入一个单向链表,输出该链表中倒数第 k 个结点.链表的倒数第 0 个结点为链表的尾指针.链表结点定义如下: struct ListNode {int m_nKey;Lis ...

  3. 输出单向链表中倒数第k个结点

    描述 输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第0个结点为链表的尾指针. 链表结点定义如下: struct ListNode { int       m_nKey; ListNode* ...

  4. Linus:利用二级指针删除单向链表

    Linus大神在slashdot上回答一些编程爱好者的提问,其中一个人问他什么样的代码是他所喜好的,大婶表述了自己一些观点之后,举了一个指针的例子,解释了什么才是core low-level codi ...

  5. 【转】Linus:利用二级指针删除单向链表

    原文作者:陈皓 原文链接:http://coolshell.cn/articles/8990.html 感谢网友full_of_bull投递此文(注:此文最初发表在这个这里,我对原文后半段修改了许多, ...

  6. C语言实现单向链表及其各种排序(含快排,选择,插入,冒泡)

    #include<stdio.h> #include<malloc.h> #define LEN sizeof(struct Student) struct Student / ...

  7. 数据结构——Java实现单向链表

    结点类: /** * @author zhengbinMac * 一个OnelinkNode类的对象只表示链表中的一个结点,通过成员变量next的自引用方式实现线性表中各数据元素的逻辑关系. */ p ...

  8. 输入一个单向链表,输出该链表中倒数第K个结点

    输入一个单向链表,输出该链表中倒数第K个结点,具体实现如下: #include <iostream> using namespace std; struct LinkNode { publ ...

  9. 单向链表JAVA代码

        //单向链表类 publicclassLinkList{       //结点类     publicclassNode{         publicObject data;         ...

  10. C++ 单向链表反转

    单向链表反转,一道常见的面试题,动手实现下. #include "stdafx.h" #include <stdlib.h> struct Node{ int data ...

随机推荐

  1. MySQL锁总结

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/78 MySQL 锁基础 参考了何登成老师文章的结构MySQL 加 ...

  2. bzoj 4872: [Shoi2017]分手是祝愿

    Description Zeit und Raum trennen dich und mich. 时空将你我分开.B 君在玩一个游戏,这个游戏由 n 个灯和 n 个开关组成,给定这 n 个灯的初始状态 ...

  3. datatable使用笔记

    这是一个使用datatable的jsp文件实例,实现了点击单元格后编辑单元格所在行的内容. <%@ page pageEncoding="UTF-8"%> <!D ...

  4. ORA-00600[17059]错误

    ORA-00600[17059] ORA-00600[17059]错误大部分都是因为高版本导致,对于本库的分析:因为该库的 shared pool老化比较频繁,到我介入的时候,发现相关该类此sql已经 ...

  5. Protobuf的简单介绍、使用和分析

      Protobuf的简单介绍.使用和分析   一.protobuf是什么? protobuf(Google Protocol Buffers)是Google提供一个具有高效的协议数据交换格式工具库( ...

  6. python中的if __name__=='__main__': main()解析

    python中我们会看到一段代码是这样的: if __name__=='__main__': main() 这段代码的什么意思,我们可以知道代码的意思是如果__name__=='__main__'为T ...

  7. wc--Linux

    这个命令的功能也很好记,因为它功能很有限: wc -c filename:显示一个文件的字节数 wc -m filename:显示一个文件的字符数 wc -l filename:显示一个文件的行数 w ...

  8. [笔记]《JavaScript高级程序设计》- 最佳实践

    一.可维护性 1 什么是可维护的代码 可理解性--其他人可以接受代码并理解它的意图和一般途径,而无需原开发人员的完整解释. 直观性--代码中的东西一看就能明白,不管其操作过程多么复杂. 可适应性--代 ...

  9. Python进阶内容(二)--- 装饰器

    谈装饰器前,需要明白一件事,Python 中的函数和 Java.C++不太一样,Python 中的函数可以像普通变量一样当做参数传递给另外一个函数,例如: def foo(): print(" ...

  10. Linux 笔记 #03# 在 Debian远程服务器上运行 Java socket程序

    我试图做什么:把我的破代码放到服务器上运行,并成功与客户端进行 socket通信. 预备环境:刚安装好 MySQL 和 JVM 的 Linux远程服务器(Debian 8)一台. 主要有如下几个步骤: ...