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)