C语言实现双向链表

 更新时间:2015年03月23日 09:21:34   投稿:hebedich  
本文给大家分享的是一段使用C语言实现双向链表的代码,完全是根据自己的理解和认识来编写的,希望大家能够喜欢,文章的最后附上了一个网友写的对于双向链表删除节点、插入节点、双向输出等操作的代码,也非常不错,推荐给大家

这个小代码是我凭自己对指针和链表的理解和认识,自己实现的,没有参考其他人的代码,如果有相同的地方,那真的只是巧合,代码我在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++ opencv ffmpeg图片序列化实现代码解析

    C++ opencv ffmpeg图片序列化实现代码解析

    这篇文章主要介绍了C++ opencv ffmpeg图片序列化实现代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • 结合C++11新特性来学习C++中lambda表达式的用法

    结合C++11新特性来学习C++中lambda表达式的用法

    这篇文章主要介绍了C++中lambda表达式的用法,lambda表达式的引入可谓是C++11中的一大亮点,同时文中也涉及到了C++14标准中关于lambda的一些内容,需要的朋友可以参考下
    2016-01-01
  • C语言实现车辆出租管理系统

    C语言实现车辆出租管理系统

    这篇文章主要为大家详细介绍了C语言实现车辆出租管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • C++11 简单实现线程池的方法

    C++11 简单实现线程池的方法

    这篇文章主要介绍了C++11 简单实现线程池的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • C++实现LeetCode(768.可排序的最大块数之二)

    C++实现LeetCode(768.可排序的最大块数之二)

    这篇文章主要介绍了C++实现LeetCode(768.可排序的最大块数之二),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++小知识:C/C++中不要按值传递数组

    C++小知识:C/C++中不要按值传递数组

    今天小编就为大家分享一篇关于C++小知识:C/C++中不要按值传递数组,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 单元测试代码覆盖率解析

    单元测试代码覆盖率解析

    单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。动态分析就是通过观察软件运行时的动作,来提供执行跟踪,时间分析,以及测试覆盖度方面的信息。下面我们来详细了解下吧
    2019-06-06
  • C++枚举类型enum与enum class的使用

    C++枚举类型enum与enum class的使用

    这篇文章主要介绍了C++枚举类型enum与enum class的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • 老生常谈C语言动态函数库的制作和使用(推荐)

    老生常谈C语言动态函数库的制作和使用(推荐)

    下面小编就为大家带来一篇老生常谈C语言动态函数库的制作和使用(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • C语言代码实现俄罗斯方块

    C语言代码实现俄罗斯方块

    这篇文章主要为大家详细介绍了C语言代码实现俄罗斯方块,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-01-01

最新评论