一、缘起

很早写了一个带头尾指针的list,该list支持从尾部插入元素,在任意位置删除元素,最近用这个list时发现一个bug,修正了,并加了几个接口函数。贴出来,希望对C的初学者有用。

二、基本说明

2.1、数据结构

l         listnode

typedef struct listnode

{

int data;           //you can add any type data here

int id;

struct listnode* next;

} *listnode, _listnode;

其中data、id用于测试程序,可换成任意数据类型。

l         list

typedef struct list

{

struct listnode* head;

struct listnode* tail;

int count;           //0 --empty

int current_id;

} *list, _list;

head、tail均指向实际元素,list为空时,指向NULL,current_id用于测试程序,可去。

2.2、函数说明

l         void list_init(list)

初始化list

l         void list_insert(list, listnode)

list的尾部插入元素

l         int list_delete(list, listnode)

从list上删除指定元素,删除成功返回1,删除失败返回0

l         void list_poll(list myroot)

遍历整个pool,测试用

l         listnode new_listnode(const int id, int data)

构建新的元素,并为其分配内存

l         void delete_listnode(listnode mylistnode)

删除指定元素,并释放其内存

l         listnode find_node_by_data(list myroot, const int data)

根据data在list上查找匹配的元素

l         listnode find_node_by_id(list myroot, const int id)

根据id在list上查找匹配的元素

三、代码

3.1、list.h:

/* list.h

** Copyright 2004 Coon Xu.

** Author: Coon Xu

** Date: 02 Feb 2005

*/

#ifndef LIST_H

#define LIST_H

#include <stdio.h>

#include <stdlib.h>

typedef struct listnode

{

int data;           //you can add any type data here

int id;

struct listnode* next;

} *listnode, _listnode;

typedef struct list

{

struct listnode* head;

struct listnode* tail;

int count;           //0 --empty

int current_id;

} *list, _list;

void list_init(list);

void list_insert(list, listnode);

int list_delete(list, listnode);

void list_poll(list myroot);

listnode new_listnode(const int id, int data);

void delete_listnode(listnode mylistnode);

listnode find_node_by_data(list myroot, const int data);

listnode find_node_by_id(list myroot, const int id);

#endif

3.2、list.c:

/* list.c

** Copyright 2004 Coon Xu.

** Author: Coon Xu

** Date: 02 Feb 2005

*/

#include "list.h"

void list_init(list myroot)

{

myroot->count = 0;

myroot->head = NULL;

myroot->tail = NULL;

myroot->current_id = 1;

}

void list_poll(list myroot)

{

printf("-------------------------------------------------------/n");

listnode p_listnode = myroot->head;

while(p_listnode != NULL)

{

printf("id: %d/t data: %d/n", p_listnode->id, p_listnode->data);

p_listnode = p_listnode->next;

}

}

//insert node at the tail

void list_insert(list myroot, listnode mylistnode)

{

myroot->count++;

mylistnode->next = NULL;

if(myroot->head == NULL)

{

myroot->head = mylistnode;

myroot->tail = mylistnode;

}

else

{

myroot->tail->next = mylistnode;

myroot->tail = mylistnode;

}

printf("[insert]:/tlist.cout:/t%d/n", myroot->count);

}

int list_delete(list myroot, listnode mylistnode)

{

struct listnode* p_listnode = myroot->head;

struct listnode* pre_listnode;

//myroot is empty

if(p_listnode == NULL)

{

return 0;

}

//delete head node

if(p_listnode == mylistnode)

{

myroot->count--;

//myroot has only one node

if(myroot->tail == mylistnode)

{

myroot->head = NULL;

myroot->tail = NULL;

}

else

{

myroot->head = p_listnode->next;

}

printf("[delete]:/tlist.cout:/t%d/n", myroot->count);

return 1;

}

while(p_listnode != NULL)

{

if(p_listnode == mylistnode)

{

break;

}

pre_listnode = p_listnode;

p_listnode = p_listnode->next;

}

if(p_listnode == NULL)

{

printf("can not find the node.../n");

return 0;

}

else

{

pre_listnode->next = p_listnode->next;

if(myroot->tail == p_listnode)

{

myroot->tail = pre_listnode;

}

myroot->count--;

printf("[delete]:/tlist.cout:/t%d/n", myroot->count);

return 1;

}

}

listnode new_listnode(const int id, int data)

{

listnode p_listnode = malloc(sizeof(_listnode));

p_listnode->id = id;

p_listnode->data = data;

return p_listnode;

}

void delete_listnode(listnode mylistnode)

{

mylistnode->next = NULL;

free(mylistnode);

mylistnode = NULL;

}

listnode find_node_by_data(list myroot, const int data)

{

listnode p_listnode = myroot->head;

while(p_listnode != NULL)

{

if( p_listnode->data == data )

{

printf("find the node for data: %d/n", data);

break;

}

p_listnode = p_listnode->next;

}

return p_listnode;

}

listnode find_node_by_id(list myroot, const int id)

{

listnode p_listnode = myroot->head;

while(p_listnode != NULL)

{

if( p_listnode->id == id )

{

printf("find the node for id: %d/n", id);

break;

}

p_listnode = p_listnode->next;

}

return p_listnode;

}

3.3、附一个测试的主程序

main.c:

#include <stdio.h>

#include <stdlib.h>

#include "list.h"

int main(int argc, char *argv[])

{

list mylist = malloc(sizeof(_list));

list_init(mylist);

int ix = 0;

for(ix = 0; ix < 10; ix++)

{

listnode my_listnode = new_listnode( (mylist->current_id)++, ix);

list_insert(mylist, my_listnode);

}

list_poll(mylist);

//delete head node and test

listnode my_listnode = find_node_by_id(mylist, 1);

list_delete(mylist, my_listnode);

delete_listnode(my_listnode);

list_poll(mylist);

//insert a node and test

my_listnode = new_listnode( (mylist->current_id)++, 100);

list_insert(mylist, my_listnode);

list_poll(mylist);

//delete tail node and test

my_listnode = find_node_by_id(mylist, 10);

list_delete(mylist, my_listnode);

delete_listnode(my_listnode);

list_poll(mylist);

//insert a node and test

my_listnode = new_listnode( (mylist->current_id)++, 200);

list_insert(mylist, my_listnode);

list_poll(mylist);

//delete a normal node and test

my_listnode = find_node_by_data(mylist, 6);

list_delete(mylist, my_listnode);

delete_listnode(my_listnode);

list_poll(mylist);

//insert a node and test

my_listnode = new_listnode( (mylist->current_id)++, 300);

list_insert(mylist, my_listnode);

list_poll(mylist);

//delete head node again and test

my_listnode = find_node_by_id(mylist, 2);

list_delete(mylist, my_listnode);

delete_listnode(my_listnode);

list_poll(mylist);

//insert a node and test

my_listnode = new_listnode( (mylist->current_id)++, 400);

list_insert(mylist, my_listnode);

list_poll(mylist);

system("PAUSE");

return 0;

}

带头尾指针的list的C实现相关推荐

  1. LeetCode刷题---707. 设计链表(双向链表-带头尾双结点)

    文章目录 一.编程题:707. 设计链表(双向链表-带头尾双结点) 1.题目描述 2.示例1: 3.提示: 二.解题思路 1.思路 2.复杂度分析: 3.算法图解(双向链表) 三.代码实现 三.单向链 ...

  2. python调用c++返回带成员指针的类指针

    这个是OK的: class Rtmp_tool { public:int m_width;AVCodecContext * c;};指针的用法如下: Rtmp_tool * rtmp_tool; rt ...

  3. python 带随机指针的链表深度复制_LeetCode:复制带随机指针的链表

    请实现 copyRandomList 函数,复制一个复杂链表.在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null. 思路: ...

  4. 不带parent指针的successor求解

    问题: 请设计一个算法,寻找二叉树中指定结点的下一个结点(即中序遍历的后继).给定树的根结点指针TreeNode* root和结点的值int p,请返回值为p的结点的后继结点的值.保证结点的值大于等于 ...

  5. python 带随机指针的链表深度复制_链表--深度拷贝一个带有随机指针的链表

    链表--深度拷贝一个带有随机指针的链表 链表--深度拷贝一个带有随机指针的链表 本文介绍两种解法. 解法1:利用一个map ListNode *copyRandomList(ListNode *hea ...

  6. 循环队列之循环队列长度和头尾指针关系

    1.为什么会引入循环队列? 对于顺序队列,头指针和尾指针开始时刻都指向数组的0下标元素.当加入新元素以后,尾指针向后移动,指向最后一个元素的下一个位置. 但是尾指针不能超过数组的最大范围.当有元素删除 ...

  7. c++带成员指针使用

    下面两种读m_width的方式都ok: class Rtmp_tool { public: int m_width= 0; int nHeight = 0; AVCodecContext *c; }; ...

  8. ReentrantLock1.8源码

    使用举例 默认是非公平锁,公平锁构造参数用true package com.study.demo;import java.util.concurrent.locks.ReentrantLock;/** ...

  9. 【数据结构笔记】3.栈和队列

    文章目录 第3章 栈和队列 3.1 栈 3.1.1 栈的基本概念 1.栈的定义 2.栈的基本操作 3.1.2 栈的顺序存储结构 1.顺序栈的实现 2.顺序栈的基本运算 3.共享栈 3.1.3 栈的链式 ...

最新文章

  1. TVM优化GPU机器翻译
  2. 为什么要阅读——兼分享《首先,打破一切常规》[中译文]:世界顶级管理者的成功秘诀/(美)马库斯·白金汉,(美)柯特·科夫曼 著...
  3. 成功解决ERROR: Could not install packages due to an EnvironmentError: [WinError 5] 拒绝访问。backend_agg.cp36
  4. c语言NULL和0区别
  5. OpenGL编程指南1:OpenGL简介
  6. boost::shared_future相关的测试程序
  7. 浅析epoll – epoll例子以及分析
  8. apache hadoop_使用Apache Hadoop计算PageRanks
  9. Docker run 命令 参数说明
  10. 吓坏了!智能锁半夜自己“离奇打开”
  11. librdkafka 安装
  12. MySQL多线程并发调优
  13. php mvc vue 调用js函数_js 匿名函数自调用
  14. [原] 计算机调试管理器服务被禁用的解决方法
  15. pq分解法中b’怎么求_1.初中数学:含参数不等式组,有两个负整数解,怎么求a的取值范围?...
  16. 【线性代数】1.3伴随矩阵和逆矩阵
  17. win10 应用商店打不开解决
  18. mysql error trace_dede源码下data/mysql_error_trace.inc日志暴露后台地址漏洞修复
  19. 什么是全栈工程师,如何成为全栈工程师
  20. 日期插件(默认显示当前日期)---年月

热门文章

  1. offline .net3.5
  2. MySQL5.6免安装配置与“系统找不到指定的文件”错误
  3. jquery 事件对象属性小结
  4. NSString的各种用法总结(创建、截取、判断比较、转化数据类型、拼接、替换、添加、追加、读取、写入、删去、改变)
  5. Table 表格导出功能
  6. apachacxf项目使用@WebService报错
  7. 逆向project实战--Acid burn
  8. 往文件中写数据--增量
  9. 【译】x86程序员手册37-第10章 初始化
  10. 20145212 《信息安全系统设计基础》第2周学习总结