双向链表的基本操作:
包含三个文件:
1.c为函数的实现
1.h为函数的声明
main.c为主函数
由于查找和跟前面三个类似,故没有实现
测试结果以及部分说明如下
1、头插法建立链表说明以及测试结果:
2、尾插法建立链表说明以及测试结果:
3、在index位置插入
4、修改index位置值
5、删除index位置
代码如下
1.c文件
/*************************************************************************
> File Name : 1.c
> Author : 潘潘的嵌入式
> Function : 函数实现
> Created Time: 2023年01月07日 星期六 09时41分35秒
************************************************************************/
#include "1.h"
//带头节点双向链表的初始化(建立一个双向循环链表)
node_t *init_list()
{
//从堆开辟空间
node_t *head = (node_t*)malloc(sizeof(node_t));
//检测是否成功
SYSERR(NULL,==,head,"malloc is error",NULL);
//初始化参数
head -> data = 0;
head -> next = NULL;
head -> pion = NULL;
return head;
}
//从堆开辟结点
node_t *creat_node(ElemType data)
{
node_t *newNode = (node_t*)malloc(sizeof(node_t));
SYSERR(NULL,==,newNode,"newNode is null",NULL);
newNode -> data = data;
newNode -> next = NULL;
newNode -> pion = NULL;
return newNode;
}
//带头结点 头插法 建立链表
int insert_hlist(node_t *head,ElemType data)
{
//检测参数合法性
SYSERR(NULL,==,head,"head is NULL",-1);
node_t *newNode = creat_node(data);
//检测是否开辟成功
SYSERR(NULL,==,newNode,"newNode is null",-2);
//将新节点插入链表
if(NULL == head -> next)//链表中只有头结点
{
head -> next = newNode;
newNode -> pion = head;
newNode -> next = NULL;
}
else
{
newNode -> next = head -> next;
newNode -> pion = head;
head -> next -> pion = newNode;
head -> next = newNode;
}
return 0;
}
//带头节点尾插法建立链表
int insert_tlist(node_t *head,ElemType data)
{
//检测参数合法性
SYSERR(NULL,==,head,"head is null",-1);
node_t *newNode = creat_node(data);
//检测是否开辟成功
SYSERR(NULL,==,newNode,"newNode is null",-2);
//找到最后一个结点
node_t *p = head;
while(NULL != p -> next)
{
p = p -> next;
}
//将新节点插入链表
newNode -> next = p -> next;
newNode -> pion = p;
p -> next = newNode;
return 0;
}
//在index位置插入一个结点
int insert_index(node_t *head,int index,ElemType data)
{
//检测参数合法性
SYSERR(NULL,==,head,"head is null",-1);
if(index <= 0)
{
printf("位置不合法\n");
return -3;
}
node_t *newNode = creat_node(data);
//检测是否开辟成功
SYSERR(NULL,==,newNode,"newNode is null",-2);
int i = 0;
node_t *p = head;
//找到要插入结点的前一个位置
while(NULL != p && i < index - 1)
{
++i;
p = p -> next;
}
//根据循环跳出的情况进行插入
if( NULL == p)
{
printf("位置不合法\n");
return -3;
}
else if(NULL == p -> next)//p为最后一个结点
{
newNode -> next = p -> next;
newNode -> pion = p;
p -> next = newNode;
}
else//p为中间结点
{
newNode -> next = p -> next;
newNode -> pion = p;
p -> next -> pion = newNode;
p -> next = newNode;
}
return 0;
}
//修改index位置值为data
int revise_index(node_t *head,int index,ElemType data)
{
//检测参数合法性
SYSERR(NULL,==,head,"head is null",-1);
if(index <= 0)
{
printf("位置不合法\n");
return -3;
}
node_t *newNode = creat_node(data);
//检测是否开辟成功
SYSERR(NULL,==,newNode,"newNode is null",-2);
int i = 0;
node_t *p = head;
//找到index位置
while(p != NULL && i < index)
{
++i;
p = p -> next;
}
if(NULL == p)
{
printf("位置不合法\n");
return -3;
}
else
{
p -> data = data;
}
return 0;
}
//删除第index个元素
int delete_index(node_t *head,int index)
{
//检测参数合法性
SYSERR(NULL,==,head,"head is null",-1);
if(index <= 0)
{
printf("位置不合法\n");
return -3;
}
//找到index前一个位置
int i = 0;
node_t *p = head;
node_t *q;
while(p != NULL && i < index -1)
{
++i;
p = p -> next;
}
//根据循环跳出的情况进行插入
if( NULL == p || NULL == p -> next)
{
printf("位置不合法\n");
return -3;
}
else if(NULL == p -> next -> next)//index为最后个结点
{
q = p -> next;
q -> pion = NULL;
p -> next = q -> next;
free(q);
}
else//index为中间结点
{
q = p -> next;
p -> next = q -> next;
q -> next -> pion = p;
free(q);
}
return 0;
}
//查找data的位置
//查找index位置的值
//打印双向链表
void show_list(node_t *head)
{
//参数合法性检测
SYSERR(NULL,==,head,"head is null",);
node_t *p = head -> next;
printf("data ");
while(NULL != p)
{
printf("%d ",p->data);
p = p -> next;
}
printf("\n");
}
1.h文件
/*************************************************************************
> File Name : 1.h
> Author : 潘潘的嵌入式
> Function : 函数定义和声明
> Created Time: 2023年01月07日 星期六 09时41分54秒
************************************************************************/
#ifndef __1_H
#define __1_H
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
//功能:安全检测宏
//@x:要检查的变量 @opt:操作符 @y:要检查的变量 @mes:报错信息 @z:返回值
#define SYSERR(x,opt,y,mes,z) if(x opt y) \
{ \
printf("%s %d %s : error %s",__FILE__,__LINE__,__func__,mes); \
return z; \
}
//双向链表
//结构体变量
typedef int ElemType; //所需要的数据类型
typedef struct node
{
ElemType data; //数据
struct node *next;//后继指针
struct node *pion;//前驱指针
}node_t;//node_t是结构体变量 node_t *是结构体指针
//功能:带头结点双向链表的初始化(建立一个双向循环链表)
//返回值:结构体指针
node_t *init_list();
//功能:从堆开辟结点
//参数:@data:数据域
//返回值:结构体指针
node_t *creat_node(ElemType data);
//功能:带头结点 头插法 建立链表
//参数:@head:链表头结点 @data:数据域
//返回值:0:成功 非0:失败
int insert_hlist(node_t *head,ElemType data);
//功能:带头结点 尾插法 建立链表
//参数:@head:链表头结点
//返回值:0:成功 非0:失败
int insert_tlist(node_t *head,ElemType data);
//功能:在index位置插入一个结点
//参数:@head:链表头结点 @index:要插入的位置 @data:要插入的值
//返回值:0:成功 非0:失败
int insert_index(node_t *head,int index,ElemType data);
//功能:修改index位置值为data
//参数:@head:链表头结点 @index:要修改的位置 @data:要修改的值
//返回值:0:成功 非0:失败
int revise_index(node_t *head,int index,ElemType data);
//功能:删除第index个元素
//参数:@head:链表头结点 @index:要删除的位置
//返回值:0:成功 非0:失败
int delete_index(node_t *head,int index);
//功能:打印双向链表
//参数:@head:链表头结点
void show_list(node_t *head);
#endif
main.c文件
/*************************************************************************
> File Name : main.c
> Author : 潘潘的嵌入式
> Function : 主函数
> Created Time: 2023年01月07日 星期六 09时42分14秒
************************************************************************/
#include "1.h"
int main(int argc, char* argv[])
{
//创建双向链表
node_t *head = init_list();
//检测是否创建成功
SYSERR(NULL,==,head,"head is null",-1);
//打印head内容 以及地址
printf("head = %p head->data = %d head->next = %p head->pion = %p\n",head,head->data,head->next,head->pion);
#if 0
//头插法测试
ElemType a[10] = {1,3,5,7,9,2,4,6,8,10};
for(int i = 0; i < 10; i++)
{
insert_hlist(head,a[i]);
}
show_list(head);
#endif
#if 1
//尾插法测试
ElemType a[10] = {1,3,5,7,9,2,4,6,8,10};
for(int i = 0; i < 10; i++)
{
insert_tlist(head,a[i]);
}
show_list(head);
#endif
#if 0
//在index位置插入测试
int index;
ElemType data;
printf("请输入你要插入的位置和数据:\n");
scanf("%d %d",&index,&data);
int res = insert_index(head,index,data);
if(!res)
{
printf("插入成功\n");
show_list(head);
}
else
{
printf("插入失败\n");
}
#endif
#if 0
//修改index位置值测试
int index;
ElemType data;
printf("请输入你要修改的位置和数据:\n");
scanf("%d %d",&index,&data);
int res = revise_index(head,index,data);
if(!res)
{
printf("修改成功\n");
show_list(head);
}
else
{
printf("修改失败\n");
}
#endif
#if 1
//删除index位置值测试
int index;
printf("请输入你要删除的位置:\n");
scanf("%d",&index);
int res = delete_index(head,index);
if(!res)
{
printf("删除成功\n");
show_list(head);
}
else
{
printf("删除失败\n");
}
#endif
return 0;
}