帶頭尾指針的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;

}

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/253893.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/253893.shtml
英文地址,請注明出處:http://en.pswp.cn/news/253893.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Gmapping——從原理到實踐

概述 在SLAM中&#xff0c;機器人位姿和地圖都是狀態變量&#xff0c;我們需要同時對這兩個狀態變量進行估計&#xff0c;即機器人獲得一張環境地圖的同時確定自己相對于該地圖的位置。我們用x表示機器人狀態&#xff0c;m表示環境地圖&#xff0c;z表示傳感器觀測情況&#xf…

關于git分支

1.關于git分支 git的“分支”乍一聽是一個特別容易讓人產生錯覺的概念&#xff0c;以為它和樹枝一樣是分叉的枝節&#xff0c;其實Git中的分支本質上是個指向commit對象的指針,每次commit&#xff0c;git都把它們串成一條時間線&#xff0c;這條時間線就是一個分支。 2.直接切換…

【機器學習經典算法源碼分析系列】-- 邏輯回歸

1.邏輯回歸&#xff08;Logistic Regression&#xff09;又常被成為“邏輯斯蒂回歸”&#xff0c;實質上是一個二元分類問題。 邏輯回歸代價函數&#xff1a; 代價函數導數&#xff1a; Matlab實現&#xff1a; 采用matlab中自帶的無約束最小化函數fminunc來代替梯度下降法&…

求特殊自然數

總時間限制: 1000ms 內存限制: 65536kB 描述一個十進制自然數,它的七進制與九進制表示都是三位數&#xff0c;且七進制與九進制的三位數碼表示順序正好相反。編程求此自然數,并輸出顯示。 輸入無。輸出三行&#xff1a;第一行是此自然數的十進制表示&#xff1b;第一行是此自然…

ROS——不同版本間ROS進行通信

在相同版本間的ROS進行通信不在贅述了&#xff0c;修改/etc/hosts文件即可。 最近項目遇到在Ubuntu16.04 與Ubuntu18.04兩個系統間進行ROS通信&#xff0c;ROS版本分別為Kinetic和Melodic。配置網絡后&#xff0c;兩邊都能夠ping通&#xff0c;但是在獲取ros數據是&#xff0c…

大數據開發實戰:數據流圖及相關數據技術

1、大數據流程圖 2、大數據各個環節主要技術 2.1、數據處理主要技術 Sqoop&#xff1a;&#xff08;發音&#xff1a;skup&#xff09;作為一款開源的離線數據傳輸工具&#xff0c;主要用于Hadoop(Hive) 與傳統數據庫&#xff08;MySql,PostgreSQL&#xff09;間的數據傳遞。它…

oracle 中時間類型 date 與 long 互轉

我們在保存時間到數據庫時&#xff0c;有時候會保存long型的數據&#xff0c;固定長度是13位&#xff0c;是用當前時間減去1970-01-01&#xff0c;再換算成毫秒得到的結果。 但是要考慮到時區問題中國的時區時8區所以時間要加上8小時 oracle中的實現方式&#xff1a; ---------…

Linux對包管理闡述

Centos/Redhat/Fedora的軟件包&#xff0c;都是rpm后綴的文件。包管理器rpm(Redhat packages manager) linux的哲學思想是簡單命令解決復雜任務&#xff0c;因此每個軟件的功能較單一&#xff0c;所以各種包之間有著復雜的依賴關系&#xff0c;為了解決這種可以使用前端工具&am…

跨時鐘域電路設計——亞穩態及雙鎖存器

一、同步電路 定義&#xff1a;電路中所有受時鐘控制的單元&#xff0c;全部由一個統一的時鐘控制。 優點&#xff1a;在同步設計中&#xff0c;EDA工具可以保證電路系統的時序收斂&#xff0c;避免電路設計中的競爭冒險。 缺點&#xff1a;時鐘樹綜合需要加入大量延遲單元&…

linux setsockopt詳解

1.closesocket&#xff08;一般不會立即關閉而經歷TIME_WAIT的過程&#xff09;后想繼續重用該socket&#xff1a; BOOL bReuseaddrTRUE; setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL)); 2. 如果要已經處于連接狀態的soket在調用closes…

[TOOLS] 移動端調試進行時 - whistle

1、本地安裝、啟動whistle 安裝實操請查看官方文檔不贅述 復制代碼 2、手機設置代理 實操請查看官方文檔 !!!注意&#xff1a;代理ip填寫whistle右上角online選項中的ip 復制代碼 3、whistle上設置對應rules、weinre whistle設置代理(!!!注意支持tunnel協議)&#xff1a; rules…

函數動態參數實現format

變量賦值一種是字符串格式化&#xff0c;一種是通過format的方式 1.字符串格式化 s"i am %s,age %d"%(Jasper,23)print(s)打印輸出&#xff1a;i am Jasper,age 232.format格式化 s"i am {name},age {age}".format(namejasper,age23)print(s)或 s2"i …

跨時鐘域電路設計——單bit信號

前面提到了簡單的雙電平鎖存器&#xff0c;下面是一些單bit同步電路。 一、慢時鐘域向快時鐘域 邊沿檢測同步器 將慢時鐘域的脈沖搬移并縮小為快時鐘域的脈沖。 既可以檢測上升沿&#xff0c;也可以檢測下降沿。 如上圖&#xff0c;慢時鐘下一個有效脈沖的最短周期為慢時鐘的…

數據同步 rsync+notify架構

rsync 同步命令&#xff0c;非常好用 notify是監控本地文件的變化的 、安裝配置 1. 安裝rsync&#xff0c;inotify-tools sudo apt-get install rsync inotify-tools 2. 拷貝rsync配置文件 mkdir /etc/rsync cp /usr/share/doc/rsync/examples/rsyncd.conf /etc/rsync/ 3. 服…

OC_KVC與KVO簡單介紹

KVC KVC概述 KVC 即 Key-value coding 鍵值編碼&#xff0c;是指iOS的開發中&#xff0c;可以允許開發者通過Key名直接訪問對象的屬性&#xff0c;或者給對象的屬性賦值。 KVC案例 interface Person : NSObjectproperty (nonatomic,assign) int age; property (nonatomic,copy)…

C語言100例01 PHP版(練習)

題目&#xff1a;有1、2、3、4個數字&#xff0c;能組成多少個互不相同且無重復數字的三位數&#xff1f;都是多少&#xff1f; 程序分析&#xff1a;可填在百位、十位、個位的數字都是1、2、3、4。組成所有的排列后再去 掉不滿足條件的排列。 代碼&#xff1a; 1 for($i1;$i&l…

嵌入式根文件系統制作

1:文件系統分類&#xff1a; 基于flash的文件系統&#xff1a;flash有兩種&#xff0c;一種是NOR,另一種NAND。NOR型 FLASH主要用于存放程序。NAND型 FLASH主要用于存放數據。NOR的特點是可在芯片內執行。這樣應用程序可以直接在flash內存內運行&#xff0c;不必再把代碼讀到…

跨時鐘域電路設計——結繩法

信號從快時鐘域到慢時鐘域過渡時&#xff0c;慢時鐘可能無法對快時鐘變化太快的信號進行采樣。 之前的同步器法對兩個時鐘間的關系有要求&#xff0c;結繩法適用于任何時鐘域之間的過渡。 結繩法的原理是將快時鐘信號的脈沖周期延長&#xff0c;等到慢時鐘周期采樣后再“解繩”…

我之理解---計時器setTimeout 和clearTimeout

今天在寫個圖片切換的問題 有動畫滯后的問題&#xff0c;才動手去查setTimeout 和clearTimeout。之前寫的圖片播放器也有類似的問題&#xff0c;有自動start按鈕 和stop按鈕&#xff0c; 其他都正常&#xff0c;問題出在每次多次快速的點擊start按鈕時&#xff0c;圖片播放的速…

002服務提供者Eureka

1、POM配置 和普通Spring Boot工程相比&#xff0c;僅僅添加了Eureka、Spring Boot Starter Actuator依賴和Spring Cloud依賴管理 <dependencies><!--添加Eureka Server依賴--><dependency><groupId>org.springframework.cloud</groupId><art…