用c语言实现单链表的创建插入和删除算法,C语言实现简单的单向链表(创建、插入、删除)及等效STL实现代码...

实现个算法,懒得手写链表,于是用C++的forward_list,没有next()方法感觉很不好使,比如一个对单向链表的最简单功能要求:

input:

1 2 5 3 4

output:

1->2->5->3->4

相当于仅仅实现了插入、遍历2个功能(当然遍历功能稍微修改就是销毁链表了)

用纯C写了份测试代码

/* 基本数据结构的定义以及函数的声明 */

typedef int ElemType;

typedef struct Node

{

ElemType elem;

struct Node* next;

} Node, * NodePtr, **ForwardList;

NodePtr createNode(ElemType x);

void showList(ForwardList lst);

void destroyList(ForwardList lst);

// 创建元素为x的节点并插入到节点where后面

// 若where为NULL, 则插入到链表lst的首部作为首节点

// 返回新节点的指针

NodePtr insertAfterNode(NodePtr where, ElemType x,

ForwardList lst);

/* 链表相关函数的具体实现 */

NodePtr createNode(ElemType x)

{

NodePtr pNode = (NodePtr) malloc(sizeof(Node));

if (pNode == NULL) {

perror("malloc");

exit();

}

pNode->elem = x;

pNode->next = NULL;

return pNode;

}

NodePtr insertAfterNode(const NodePtr where,

ElemType x, ForwardList lst)

{

NodePtr pNode = createNode(x);

if (where == NULL) {

*lst = pNode;

} else {

pNode->next = where->next;

where->next = pNode;

}

return pNode;

}

void showList(ForwardList lst)

{

printf("显示链表: ");

NodePtr curr = *lst;

while (curr->next != NULL) {

printf("%d->", curr->elem);

curr = curr->next;

}

printf("%d\n", curr->elem);

}

void destroyList(ForwardList lst)

{

printf("销毁链表: ");

NodePtr curr = *lst;

while (curr != NULL) {

NodePtr next = curr->next;

printf("%d ", curr->elem);

free(curr);

curr = next;

}

printf("\n");

}

/* 测试代码 */

int main()

{

NodePtr head = NULL;

initListFromStdin(&head);

showList(&head);

destroyList(&head);

return ;

}

三个部分都是写在一份代码里(forward_list.c)的,测试结果如下

$ ls

data.in forward_list.c

$ cat data.in

$ gcc forward_list.c -std=c99

$ ./a.out

显示链表: ->->->->

销毁链表:

由于是不需要考虑周全的C代码,所以很多C++的一些工程性的技巧不需考虑,比如模板、const,说起来之前没把C代码封装成函数的时候就曾经导致链表的头节点被修改,最后销毁链表时,遍历后头节点直接指向了最后一个节点,导致前4个节点都没被销毁。如果合理地使用const,在编译期就能检查出来。

嘛,其实这么一写下来,C++的forward_list版本也就写出来了,毕竟我的链表插入函数就是模仿forward_list的,但是写出来有点别扭。因为需要遍历到倒数第2个节点停止,最后代码如下

#include

#include

using namespace std;

// 取得前向迭代器it的下一个迭代器

template

FwIter nextIter(FwIter it)

{

return ++it;

}

int main()

{

forward_list lst;

int x;

for (auto it = lst.before_begin();

fscanf(stdin, "%d", &x) == 1;

)

{

it = lst.emplace_after(it, x);

}

// 按照a0->a1->...->an的格式输出

auto it = lst.begin();

while (nextIter(it) != lst.end())

{

printf("%d->", *it++);

}

printf("%d\n", *it);

return 0;

}

既然C++不提供next()函数那就只有手写一个,因为迭代器传参数时拷贝了一份,所以nextIter()直接返回++it并不会对原迭代器进行修改,而是修改的原迭代器的拷贝。

注意一点就是,在顺序插入构建链表时需要记录链表最后一个节点,跟我的C代码实现风格一致(好吧其实我本来就是仿STL实现的)。

那么初始值就是before_begin()而不是begin(),因为空链表不存在begin(),确切的说空链表的初始节点为NULL。

测试代码,这里_M_node是glibc++的forward_list迭代器底层实现部分,并不是跨平台代码。迭代器相当于把节点地址进行了一层封装,而_M_node则是节点地址。

#include

#include

int main()

{

std::forward_list lst;

printf("begin()地址: %p\n", lst.begin()._M_node);

printf("before_begin()地址: %p\n", lst.before_begin()._M_node);

return ;

}

结果如下:

$ g++ test.cc -std=c++

$ ./a.out

begin()地址: (nil)

before_begin()地址: 0x7fffb0896b60

[PHP] 数据结构-链表创建-插入-删除-查找的PHP实现

链表获取元素1.声明结点p指向链表第一个结点,j初始化1开始2.j

单链表创建、删除、查找、插入之C语言实现

本文将详细的介绍C语言单链表的创建.删除.查找.插入以及输出功能 一.创建 #include #include typedef int E ...

链表的C++实现——创建-插入-删除-输出-清空

注:学习了数据结构与算法分析后,对链表进行了C++实现,参考博文:http://www.cnblogs.com/tao560532/articles/2199280.html 环境:VS2013 // ...

单链表的插入删除操作(c++实现)

下列代码实现的是单链表的按序插入.链表元素的删除.链表的输出 // mylink.h 代码 #ifndef MYLINK_H #define MYLINK_H #include

c简单的单向链表

ps:list链表  node节点 在链表中节点就是一个个的结构体 堆空间由于在申请内存时,地址是随机的,所以要用链表的方式将其连接起来,但是链表头的地址要知道. 每个节点包含两个部分:数据区和地址区 ...

jQuery 节点操作(创建 插入 删除 复制 替换 包裹)

一,创建元素节点: 第1个步骤可以使用jQuery的工厂函数$()来完成,格式如下: $(html); $(html)方法会根据传入的HTML标记字符串,创建一个DOM对象,并将这个DOM对象包装成一 ...

(C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作

上午写了下单向循环链表的程序,今天下午我把双向链表的程序写完了.其实双向链表和单向链表也是有很多相似的地方的,听名字可以猜到,每个节点都包含两个指针,一个指针指向上一个节点,一个指针指向下一个节点.这 ...

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

Object-C 作为C 的包装语言(运行时.消息机制).如果不熟悉C 的话实在玩得太肤浅. 随便深入oc 内部都会接触到C. runtime .GCD.Block.消息机制... 所有强大的功能无不 ...

原生JS实现单向链表

1.前言 用JS实现一个简单的单向链表,并完成相关的功能 2.功能说明 push(value):从链表尾部添加一个新的节点 insertAfer(value,item):向链表中的item节点之后插入 ...

随机推荐

css 通用reset,common

/*------------------------------------*\ $RESET \*------------------------------------*/ body, div, ...

ajax是什么

1.ajax是什么? ajax: asynchronous javascript and xml: 异步的javascript和xml. ajax是一种用来改善用户体验的技术,其本质是利用浏览器内置的 ...

MyBatis动态传入表名,字段名参数的解决办法

原文:http://blog.csdn.net/xichenguan/article/details/50393748 要实现动态传入表名.列名,需要做如下修改 添加属性statementType=& ...

用 LSTM 做时间序列预测的一个小例子(转自简书)

问题:航班乘客预测 数据:1949 到 1960 一共 12 年,每年 12 个月的数据,一共 144 个数据,单位是 1000 下载地址 目标:预测国际航班未来 1 个月的乘客数 import nu ...

OpenTK教程-2绘制一个三角形(正确的方式)

上一个教程向我们展示了如何在屏幕上画一个三角形.但是,我说过,那是一种古老的方式,即使它能够正常运行,但是现在这已经不是"正确"的方式.上篇文章中我们将几何发送到GPU的方式是所谓 ...

xslt中substring 函数的用法

1.函数定义: string substring(string, number, number?) 2.xslt中substring 函数功能: 返回第一个参数中从第二个参数指定的位置开始.第三个参数 ...

Arctic Network---poj2349 最小生成树

http://poj.org/problem?id=2349 题意:有n个点给出坐标,点和点之间可以用无线电或者卫星通信,每个点都有无线电收发器可进行无线电通信,但是只有m个点有卫星通信功能.卫星通信 ...

linux 常用操作以及概念

一.常用操作以及概念 查看LINUX发行版的名称及其版本号的命令: lsb_release -a cat /etc/redhat-release(针对redhat,Fedora) 0.rpm包路径:/ ...

Codeforces Beta Round #79 (Div. 1 Only) B. Buses 树状数组

http://codeforces.com/contest/101/problem/B 给定一个数n,起点是0  终点是n,有m两车,每辆车是从s开去t的,我们只能从[s,s+1,s+2....t-1 ...

你可能感兴趣的:(用c语言实现单链表的创建插入和删除算法,C语言实现简单的单向链表(创建、插入、删除)及等效STL实现代码...)