双向链表C语言版

1、声明链表节点操作函数 linklist.h

#ifndef LINKLIST_H__
#define LINKLIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

//#define TAIL_ADD
#define HEAD_ADD
typedef int LinkDataType;
// 构造节点
struct LinkNode
{
   LinkDataType data;
   struct LinkNode* pre;
   struct LinkNode* next;
};
typedef struct LinkNode LinkNode;

/**创建带头结点链表*/
LinkNode*  create_linklist();

LinkNode*  get_link_node(LinkNode*  node);

/**新增节点*/
int  insert_link_node(LinkNode*  link,LinkDataType data);

/**修改节点*/
int  update_link_node(LinkNode*  link,LinkDataType data,int index);

bool  is_end(LinkNode*  link,LinkNode*  node);

void  show_link_node(LinkNode* node);

/**节点查询*/
int   find_link_node(LinkNode* link,LinkDataType data);

void  show_link(LinkNode* link);

/**链表销毁*/
void  destory_link(LinkNode* link);

int*  get_arr();

#endif

2、定函数实现linklist.c

#include "linklist.h"

LinkNode*  create_linklist()
{
    LinkNode* link =  malloc(sizeof(LinkNode*));
    if(link == NULL)
    {
        perror("create_linklist  fail");
        exit(0);
    }
    link->next = link;
    link->pre  = link;
    link->data = 0;
    return link;
}

int  insert_link_node(LinkNode*  link,LinkDataType data)
{
    LinkNode* node =  malloc(sizeof(LinkNode*));
    if(node == NULL)
    {
        perror("node  init  fail");
        exit(0);
    }
    node->data = data;
    /// 头插法
    #ifdef HEAD_ADD
    node->pre = link;
    node->next = link->next;
    link->next->pre = node;
    link->next = node; 
    #endif

    ///尾插法
    #ifdef TAIL_ADD
    node->next = link;
    node->pre =  link->pre;
    link->pre->next = node;
    link->pre = node;
    #endif
    return 0;
}

LinkNode*  get_link_node(LinkNode*  node)
{
    LinkNode*  tmp = NULL;
    #ifdef HEAD_ADD
    tmp =  node->next;
    #endif

    #ifdef TAIL_ADD
    tmp =  node->pre;
    #endif
    return tmp;
}

bool  is_end(LinkNode*  link,LinkNode*  node)
{
     #ifdef HEAD_ADD
     return node->next==link->pre;   
     #endif

    #ifdef TATL_ADD
     return node->pre==link->next
    #endif
}

int  delete_link_node(LinkNode* link,LinkDataType data)
{
   LinkNode*  node = link;
   while (node)
   {
      if(node->data == data)
      {
         LinkNode*  next_tmp = get_link_node(node);
         node->pre->next = node->next;
         node->next->pre = node->pre;
         free(node);
         node = next_tmp;  
     }
   }
   return 0;  
}

int  update_link_node(LinkNode*  link,LinkDataType data,int index)
{
  int c = 0;
  LinkNode*  node = link;
  while (node)
  {
    if(c == index)
    {
       node->data = data;
       return c;
    }
    node = get_link_node(node);
    if(is_end(link,node))
       break;
   }
   return -1;
}

int  find_link_node(LinkNode* link,LinkDataType data)
{
    int  index =0;
    LinkNode*  node = link;
    while (node)
    {
        if(node->data==data)
        {
           return index;
        }
        node = get_link_node(node);
        index++;
        if(is_end(link,node))
           break;
    }
    return -1;
}

void  show_link_node(LinkNode* node)
{
    int  pre_data = 0;
    int  next_data = 0;
    int  data = node->data;
    if(node->pre!=NULL)
    {
       pre_data = node->pre->data;
    }
    if(node->next!=NULL)
    {
        next_data = node->next->data;
    }
    printf("%d, %d, %d \n",pre_data,data,next_data);
}

void show_link(LinkNode* link)
{
     LinkNode*  node = link;
     while (!is_end(link,node))
     {
        show_link_node(node);
        node = get_link_node(node);
     }
}

void  destory_link(LinkNode* link)
{
    LinkNode*  node = link;
    while (node)
    {
        LinkNode* tmp = get_link_node(node);
        free(node);
        node = tmp;
        if(is_end(link,node))
           break;
    }
}

int*  get_arr()
{
   int len =10;
   int* arr = malloc(len*sizeof(int*));
   int i=0;
   for(;i<len;i++)
   {
     arr[i]=i;
   }
   return arr;
}

3、编写测试函数main.h  main.c

    main.h函数定义定义

#ifndef MAIN_H__
#define MAIN_H__
#include "linklist.h"

void  test_double_link_list()
{
   LinkNode*  link = create_linklist();
   int* arr = get_arr();
   int i=0;
   for(;i<10;i++)
   {
    insert_link_node(link,*(arr+i));  
   }
   show_link(link);
   free(link);
   free(arr);
};


#endif

 main.c调用测试

#include "main.h"

int main()
{
   test_double_link_list();
   exit(0);
}

4、编写Makefile文件

#$^ 表示所有的依赖文件
#$@ 表示生成的目标文件
#$< 代表第一个依赖文件
#dapp: main.o
#	gcc main.o  -o dsapp
#main.o: main.c 
#	gcc -c  main.c  -o  main.o
#SRCS += $(wildcard *.c)
#INCS += $(wildcard *.h)

BUILD_DIR = ./build
TARGET_COMPILE += $(BUILD_DIR)/main.o  $(BUILD_DIR)/linklist.o
TARGET_EXE  = dsapp.out

all: msg $(TARGET_EXE)  clean  

#输出环境变量
msg:
	@echo $(CC) @echo $(RM)

#生成可执行文件
# 链接动态库要放在.o文件后面
# $@ 取的是输入变量(即$(TARGET_COMPILE )所指向的main.o 、linklist.o等) 
# $^ 取得是输出目标(即$(TARGET_exe)所指向的 dsapp.out)
$(TARGET_EXE): $(TARGET_COMPILE)
	$(CC) -Wall  $^  -o  $@

#执行编译
$(BUILD_DIR)/%.o: %.c
	$(CC) -Wall -c $^ -o $@

#删除编译文件
clean: $(TARGET_COMPILE) 
	$(RM) $(TARGET_COMPILE) 


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值