C语言实现双向链表
更新时间:2020年4月25日 17:39 点击:1365
这个小代码是我凭自己对指针和链表的理解和认识,自己实现的,没有参考其他人的代码,如果有相同的地方,那真的只是巧合,代码我在ubuntu 15.04下测试通过,可能存在很多错误和漏洞.
doublelist.c
/************************************************************************* > File Name: doublelist.c > Author: ChenYiLiang > Mail: chenyiliangex@163.com > Created Time: Sat 21 Mar 2015 07:32:22 PM CST ************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> struct userdata{ int userid; char username[30]; struct userdata *previous; struct userdata *next; }; struct userdata *header; size_t scanf_id; char scanf_name[30]; int yesno; int deletePosition; int alterPosition; int alterId; char alterName[30]; int searchPosition; FILE *ptr_fpid; /*向链表中插入数据*/ int insert_list(struct userdata *header, size_t position, char name[], size_t id); /*删除链表中指定的节点*/ int delete_node(struct userdata *header, size_t position); /*修改指定位置的节点信息*/ int alter_node(struct userdata *header, size_t position, size_t id, char name[]); /*查找链表中的数据*/ struct userdata *search_node(struct userdata *header, size_t position); /*遍历链表*/ int travel_list(struct userdata *header); /*判断链表是空*/ int isempty(struct userdata *header); /*将链表结构写入文件*/ int write_into_file(struct userdata *header, FILE *fp); /*从文件读取数据放到链表中*/ int read_from_file(struct userdata *header, FILE *fp); int main(){ struct userdata *header_node = (struct userdata *)malloc(sizeof(struct userdata)); header_node -> previous = NULL; header_node -> next = NULL; read_from_file(header_node, ptr_fpid); travel_list(header_node); while(1){ //scanf("%*[^\n]"); //scanf("%*c"); //scanf("%*[^\n]"); printf("please input id - "); scanf("%d", &scanf_id); //scanf("%*c"); //scanf("%*[^\n]"); printf("please input your name - "); scanf("%s", scanf_name); printf("%d - %s\n\n", scanf_id, scanf_name); //isempty(header_node); /*0表示默认插入到链表的尾部*/ insert_list(header_node, 0, scanf_name, scanf_id); //write_into_file(header_node, ptr_fpid); //isempty(header_node); printf("input anymore - "); scanf("%d", &yesno); if(yesno == -1){ break; } scanf("%*c"); scanf("%*[^\n]"); // travel_list(header_node); } getchar(); //printf("delete position data - "); //scanf("%d", &deletePosition); //delete_node(header_node, deletePosition); // printf("alter data for position - "); // scanf("%d", &alterPosition); // printf("please inout new id - "); // scanf("%d",&alterId); // printf("please input new name - "); // scanf("%s", alterName); // alter_node(header_node, alterPosition, alterId, alterName); write_into_file(header_node, ptr_fpid); travel_list(header_node); printf("\n\n"); printf("please input position to search - "); scanf("%d", &searchPosition); struct userdata *searchData = search_node(header_node, searchPosition); printf("%d\n", searchData -> userid); printf("%s\n", searchData -> username); return 0; } /* 插入节点 */ int insert_list(struct userdata *header, size_t position, char name[], size_t id ){ struct userdata *temp_newuser = header; struct userdata *getMemory = (struct userdata *)malloc(sizeof(struct userdata)); getMemory -> userid = id; strncpy(getMemory -> username, name, 30); /*当position == 0时,表示默认插入到链表的尾部*/ if(0 == position){ if(NULL != temp_newuser -> next){ while(NULL != temp_newuser -> next){ temp_newuser = temp_newuser -> next; } } } /*当position > 1时则寻找合适的位置插入*/ if(1 <= position){ for(int i = 0; i <= position; i++){ /*当执行此处的代码时表示,链表已经到达尾部或者是空链表*/ if(NULL == temp_newuser -> next){ break; } temp_newuser = temp_newuser -> next; } } getMemory -> previous = temp_newuser; if(temp_newuser -> next == NULL){ temp_newuser -> next = getMemory; getMemory -> next = NULL; }else{ temp_newuser -> next -> previous = getMemory; getMemory -> next = temp_newuser -> next; temp_newuser -> next = getMemory; } return 0; } /*删除链表中指定的节点*/ int delete_node(struct userdata *header, size_t position){ int is_empty = isempty(header); if(0 == is_empty){ printf("this si a empty list!\n\n"); return -1; } struct userdata *deleteNode = header; for(int i = 0; i < position; i++ ){ /*当执行此处的代码时表示,链表已经到达尾部或者是空链表*/ if(NULL == deleteNode -> next){ break; } deleteNode = deleteNode -> next; } /**/ deleteNode -> next -> previous = deleteNode -> previous; deleteNode -> previous -> next = deleteNode -> next; free(deleteNode); return 0; } /*修改指定位置的节点信息*/ int alter_node(struct userdata *header, size_t position, size_t id, char name[]){ int isEmpty = isempty(header); if(0 == isEmpty){ printf("this is a empty list\n\n"); return -1; } struct userdata *alterNode = header; for(int i = 0; i < position; i++ ){ /*当执行此处的代码时表示,链表已经到达尾部或者是空链表*/ if(NULL == alterNode -> next){ break; } alterNode = alterNode -> next; } alterNode -> userid = id; strncpy(alterNode -> username, name, 30); return 0; } /*查找链表中的数据*/ struct userdata *search_node(struct userdata *header, size_t position){ int isEmpty = isempty(header); if(0 == isEmpty){ printf("this is a empty!\n"); return NULL; } struct userdata *searchNode = header; for(int i = 0; i < position; i++){ if(NULL == searchNode -> next){ break; } searchNode = searchNode -> next; } return searchNode; } /*遍历链表*/ int travel_list(struct userdata *header){ struct userdata *travel = header; if(NULL == travel -> next){ printf("This is a empty list!!\n"); return 1; } for(travel = travel -> next ; ; travel = travel -> next){ printf("%d\n",travel -> userid); printf("%s\n", travel -> username); if(NULL == travel -> next){ break; } } return 1; } /*判断链表是空*/ int isempty(struct userdata *header){ if(header -> next == NULL){ return 0; }else{ return 1; } } /*将链表结构写入文件*/ int write_into_file(struct userdata *header, FILE *fp){ fp = fopen("listdata", "wb"); if(NULL == fp){ perror("open file failed when write into file!"),exit(-1); } printf("come into write!\n"); for(struct userdata *move = header -> next; ; move = move -> next){ fwrite(move,sizeof(struct userdata), 1, fp); if(NULL == move -> next){ break; } } fclose(fp); fp = NULL; return 0; } /*从文件读取数据放到链表中*/ int read_from_file(struct userdata *header, FILE *fp){ struct userdata *readfile = header; fp = fopen("listdata", "rb"); if(NULL == fp){ perror("open file failed when read - "); return -1; } while(1){ struct userdata *newread = (struct userdata *)malloc(sizeof(struct userdata)); fread(newread, sizeof(struct userdata), 1, fp); if(feof(fp)){/*当读取到文件的尾部时.跳出循环*/ break; } readfile -> next = newread; newread -> next = NULL; newread -> previous = readfile; readfile = newread; } fclose(fp); fp = NULL; return 0; }
C语言实现双向链表删除节点、插入节点、双向输出等操作
#include<cstdio> #include<cstdlib> typedef struct DoubleLinkedList { int data; struct DoubleLinkedList *pre; struct DoubleLinkedList *next; }DlinkedList_Node; //建立链表 DlinkedList_Node* createDLink() { DlinkedList_Node *head,*p,*s; int x; head = (DlinkedList_Node*)malloc(sizeof(DlinkedList_Node)); p = head; while(1) { printf("please input the data: \n"); scanf("%d",&x); if(x != 65535) { s = (DlinkedList_Node*)malloc(sizeof(DlinkedList_Node)); s ->data = x; s-> pre = p; p->next = s; p=s; } else { printf("\n数据输入结束\n"); break; } } p->next = NULL; head = head ->next; head->pre = NULL; return head; } //顺序、反序打印链表 void printDLink(DlinkedList_Node *head) { DlinkedList_Node *p,*s; p = head; printf("正序输出双向链表:\n"); while(p) { printf("%d ",p->data); s = p; p = p->next; } printf("\n 逆序输出双向链表: \n"); while(s) { printf("%d ",s->data); s = s->pre; } printf("\n \n"); } //删除一个结点 DlinkedList_Node* deleteDlinkedList_Node(DlinkedList_Node *head,int i) { DlinkedList_Node *p; p = head; if(p->data == i) { head = p->next; head->pre = NULL; free(p); return head; } while(p) { if(p->data == i) { p->pre->next = p->next; p->next->pre = p->pre; free(p); return head; } p = p->next; } printf("没有找到想要删除的数据\n"); return head; } //插入一个结点 DlinkedList_Node* insertDlinkedList_Node(DlinkedList_Node *head,int i) { DlinkedList_Node *p,*temp; p = head; temp = (DlinkedList_Node*)malloc(sizeof(DlinkedList_Node)); temp ->data = i; if(i < p->data)//比头结点数据小,插入到链表头部 { head = temp; head->next = p;//此处p为原来的head head->pre = NULL; p->pre = head;//此处p为原来的head return head; } while(p != NULL && i > p->data)//寻找合适的插入位置 { p = p->next; } if(i < p->data)//在链表中间某处找到合适插入位置 { temp ->next = p; temp ->pre = p->pre; p ->pre->next = temp; p ->pre = temp; return head; } else//没有找到合适的位置,只有将数据插入到链表尾部 { p->next = temp; //遍历到链表尾部,p==NULL temp ->pre = p; temp ->next = NULL; return head; } } int main() { DlinkedList_Node *head; head = createDLink(); printDLink(head); head = insertDlinkedList_Node(head,1012); head = deleteDlinkedList_Node(head,1991); printDLink(head); } /***************************** 运行结果如下: please input the data: 1991 please input the data: 1992 please input the data: 2013 please input the data: 2014 please input the data: 512 please input the data: 420 please input the data: 65535 数据输入结束 正序输出双向链表: 1991 1992 2013 2014 512 420 逆序输出双向链表: 420 512 2014 2013 1992 1991 正序输出双向链表: 1012 1992 2013 2014 512 420 逆序输出双向链表: 420 512 2014 2013 1992 1012 ******************************/
以上就是本文给大家分享的全部内容了,希望对大家更加熟悉C语言双向链表能够有所帮助。
上一篇: C++ const修饰变量和修饰函数介绍
下一篇: 使用C++制作简单的web服务器(续)
相关文章
- 这篇文章主要为大家详细介绍了C语言实现放烟花的程序,有音乐播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-23
- 本篇文章主要介绍C语言中char的知识,并附有代码实例,以便大家在学习的时候更好的理解,有需要的可以看一下...2020-04-25
- 这篇文章主要介绍了详解如何将c语言文件打包成exe可执行程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-25
- free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
- 这篇文章主要介绍了C语言中计算正弦的相关函数总结,包括正弦和双曲线正弦以及反正弦的函数,需要的朋友可以参考下...2020-04-25
详解C语言中的rename()函数和remove()函数的使用方法
这篇文章主要介绍了详解C语言中的rename()函数和remove()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25- 这篇文章主要介绍了C语言中求和、计算平均值、方差和标准差的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-10
- 本篇文章主要讲解C语言 基本语法,这里提供简单的示例和代码来详细讲解C语言的基本语法,开始学习C语言的朋友可以看一下,希望能够给你带来帮助...2021-09-18
- 这篇文章主要介绍了C语言中send()函数和sendto()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25
- 今天小编就为大家分享一篇C语言实现从文件读入一个3*3数组,并计算每行的平均值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了C语言中memcpy 函数的用法详解的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了使用C语言操作文件的基本函数整理,包括创建和打开以及关闭文件的操作方法,需要的朋友可以参考下...2020-04-25
- 这篇文章主要为大家详细介绍了JavaScript数据结构之双向链表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-03-07
- 这篇文章主要介绍了C语言中查找字符在字符串中出现的位置的方法,分别是strchr()函数和strrchr()函数的使用,需要的朋友可以参考下...2020-04-25
- 很多同学在学习c语言的时候是不是会碰到a++和++a都有甚么作用啊。今天我们就来探讨下...2020-04-25
- 这篇文章主要对C语言中const关键字的用法进行了详细的分析介绍,需要的朋友可以参考下...2020-04-25
- 下面小编就为大家带来一篇C语言实现时间戳转日期的算法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了C语言之整数划分问题(递归法)实例代码的相关资料,需要的朋友可以参考下...2020-04-25
C语言正则表达式详解 regcomp() regexec() regfree()用法详解
C语言处理正则表达式常用的函数有regcomp()、regexec()、regfree()和regerror(),这里就为大家介绍一下,需要的朋友可以参考一下啊...2020-04-25- 本文给大家简单介绍下c实现linux下的数据库备份的方法和具体的源码,十分的实用,有需要的小伙伴可以参考下。...2020-04-25