带头尾指针的list的C实现
一、缘起
很早写了一个带头尾指针的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实现相关推荐
- LeetCode刷题---707. 设计链表(双向链表-带头尾双结点)
文章目录 一.编程题:707. 设计链表(双向链表-带头尾双结点) 1.题目描述 2.示例1: 3.提示: 二.解题思路 1.思路 2.复杂度分析: 3.算法图解(双向链表) 三.代码实现 三.单向链 ...
- python调用c++返回带成员指针的类指针
这个是OK的: class Rtmp_tool { public:int m_width;AVCodecContext * c;};指针的用法如下: Rtmp_tool * rtmp_tool; rt ...
- python 带随机指针的链表深度复制_LeetCode:复制带随机指针的链表
请实现 copyRandomList 函数,复制一个复杂链表.在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null. 思路: ...
- 不带parent指针的successor求解
问题: 请设计一个算法,寻找二叉树中指定结点的下一个结点(即中序遍历的后继).给定树的根结点指针TreeNode* root和结点的值int p,请返回值为p的结点的后继结点的值.保证结点的值大于等于 ...
- python 带随机指针的链表深度复制_链表--深度拷贝一个带有随机指针的链表
链表--深度拷贝一个带有随机指针的链表 链表--深度拷贝一个带有随机指针的链表 本文介绍两种解法. 解法1:利用一个map ListNode *copyRandomList(ListNode *hea ...
- 循环队列之循环队列长度和头尾指针关系
1.为什么会引入循环队列? 对于顺序队列,头指针和尾指针开始时刻都指向数组的0下标元素.当加入新元素以后,尾指针向后移动,指向最后一个元素的下一个位置. 但是尾指针不能超过数组的最大范围.当有元素删除 ...
- c++带成员指针使用
下面两种读m_width的方式都ok: class Rtmp_tool { public: int m_width= 0; int nHeight = 0; AVCodecContext *c; }; ...
- ReentrantLock1.8源码
使用举例 默认是非公平锁,公平锁构造参数用true package com.study.demo;import java.util.concurrent.locks.ReentrantLock;/** ...
- 【数据结构笔记】3.栈和队列
文章目录 第3章 栈和队列 3.1 栈 3.1.1 栈的基本概念 1.栈的定义 2.栈的基本操作 3.1.2 栈的顺序存储结构 1.顺序栈的实现 2.顺序栈的基本运算 3.共享栈 3.1.3 栈的链式 ...
最新文章
- TVM优化GPU机器翻译
- 为什么要阅读——兼分享《首先,打破一切常规》[中译文]:世界顶级管理者的成功秘诀/(美)马库斯·白金汉,(美)柯特·科夫曼 著...
- 成功解决ERROR: Could not install packages due to an EnvironmentError: [WinError 5] 拒绝访问。backend_agg.cp36
- c语言NULL和0区别
- OpenGL编程指南1:OpenGL简介
- boost::shared_future相关的测试程序
- 浅析epoll – epoll例子以及分析
- apache hadoop_使用Apache Hadoop计算PageRanks
- Docker run 命令 参数说明
- 吓坏了!智能锁半夜自己“离奇打开”
- librdkafka 安装
- MySQL多线程并发调优
- php mvc vue 调用js函数_js 匿名函数自调用
- [原] 计算机调试管理器服务被禁用的解决方法
- pq分解法中b’怎么求_1.初中数学:含参数不等式组,有两个负整数解,怎么求a的取值范围?...
- 【线性代数】1.3伴随矩阵和逆矩阵
- win10 应用商店打不开解决
- mysql error trace_dede源码下data/mysql_error_trace.inc日志暴露后台地址漏洞修复
- 什么是全栈工程师,如何成为全栈工程师
- 日期插件(默认显示当前日期)---年月