(近期我在学习数据结构,于是我自己整理了单链表、循环单链表、双向链表、双向循环链表的相关代码,以巩固这段时间的学习,也希望能够帮助初学者,希望大家在阅读以下代码时发现问题纠正于我,一起探讨)
DoubleList.h
#ifndef __DOUBLELIST_H
#define __DOUBLELIST_H
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
typedef int ElemType;
//定义每一个结点的结构
typedef struct Node
{
struct Node *prev; //每个结点的前驱
ElemType data; //结点的值
struct Node *next; //每个结点的后继
}Node;
//定义双向链表结构
typedef struct Doublelist
{
Node head; //头结点
int count; //记录一个双向链表的结点的数目
}Doublelist, *pDoulist;
//初始化链表函数
void InitDoublelist(pDoulist list);
//插入节点函数
void InsertDoublelist(pDoulist list, ElemType val , int pos);
//头插函数
void InsertHeadDoublelist (pDoulist list,ElemType val);
//尾插函数
void InsertTailDoublelist(pDoulist list,ElemType val);
//删除结点函数
void DeleteDoublelist(pDoulist list,int pos);
//删除头结点的函数
void DeleteHeadDoublelist(pDoulist list);
//删除尾结点的函数
void DeleteTailDoublelist(pDoulist list);
//销毁链表函数
void DestroyDoublelist(pDoulist list);
//顺序输出结点数据函数1
void Show1(pDoulist list);
//顺序输出结点数据函数2
void Show2(pDoulist list);
//逆序输出结点数据函数
void Reverseshow(pDoulist list);
#endif
DoubleList.c
#include"DoubleList.h"
//初始化双向链表
void InitDoublelist(pDoulist list)
{
assert(list != NULL);
list->head.next = NULL; //初始化尾指针
list->head.prev = NULL; //初始化头指针
list->count = 0; //初始化结点个数i
}
//在双向链表中插入一个结点
//1:先考虑普通情况下的结点插入
/*
void InsertDoublelist(pDoulist list, ElemType val, int pos)
{
assert(list != NULL);
if( pos < 0 | pos > list->count )
{
printf("pos is error\n");
return ;
}
Node *p = &list->head;
Node *s = ( Node *)malloc(sizeof(Node));
while( pos > 0)
{
p = p->next;
pos--;
}
s->data = val;
if( p->next != NULL)
{
p->next->prev = s;
}
s->next = p->next;
s->prev = p;
p->next = s;
list->count++;
}
*/
//2:考虑特殊情况的结点插入优化代码(list->count == 0 和 pos == list->count )
static Node *BuyNode(ElemType val, Node *prev, Node *next )//购买结点
{
Node *s = (Node *)malloc(sizeof(Node));
assert( s != NULL);
s->data = val;
s->prev = prev;
s->next = next;
return s;
}
void InsertDoublelist(pDoulist list, ElemType val, int pos)
{
assert( list != NULL);
if( (pos < 0) || (pos > list->count))
{
printf("pos is error\n");
return ;
}
Node *p = &list->head;
while( pos > 0)
{
p = p->next;
pos --;
}
Node *s = BuyNode( val, p, p->next);//插入结点
if( p->next != NULL)//考虑尾插
{
p->next->prev = s;
}
p->next = s;
list->count++;
}
//头插函数
void InsertHeadDoublelist (pDoulist list,ElemType val)
{
InsertDoublelist(list, val, 0);//头插函数可以调用插入函数,将插入函数的pos参数设置为0
}
//尾插函数
void InsertTailDoublelist(pDoulist list,ElemType val)
{
InsertDoublelist(list, val, list->count);//尾插函数可以调用插入函数,将插入函数的pos参数设置为list->count
}
//删除双向链表中的一个结点
void DeleteDoublelist(pDoulist list,int pos)
{
assert(list != NULL);
if((pos < 1) ||(pos > list->count))
{
printf("pos is error\n");
return ;
}
Node * p = &list->head;
while( pos > 0)
{
p = p->next;
pos --;
}
p->prev->next = p->next;
if ( p->next != NULL)
{
p->next->prev = p->prev;
}
free(p);
list->count--;
}
//删除头结点的函数
void DeleteHeadDoublelist(pDoulist list)
{
DeleteDoublelist(list,1);//头结点的删除可以调用删除函数,将删除函数的pos参数设置为1
}
//删除尾结点的函数
void DeleteTailDoublelist(pDoulist list)
{
DeleteDoublelist(list,list->count);//尾结点的删除可以调用删除函数,将删除函数的pos参数设置为list->count
}
//输出双向链表中的数据1
void Show1(pDoulist list)
{
assert(list != NULL);
Node *p = list->head.next;
while( p != NULL)//用指针遍历整个链表,指针跑一个输出一个
{
printf("%3d",p->data);
p = p->next;
}
printf("\n");
}
void Show2(pDoulist list)
{
assert( list != NULL);
Node *p = list->head.next;
int tmp = list->count;
while( tmp > 0)
{
printf("%3d",p->data);
p = p->next;
tmp --;
}
printf("\n");
}
//逆序输出双向链表中的数据
void Reverseshow(pDoulist list)
{
assert( list != NULL);
Node *p = &list->head;
while( p->next != NULL)//先让指针跑到最后一个结点
{
p = p->next;
}
while( p->prev != NULL)//指针开始往前跑,指针跑一个输出一个值
{
printf("%3d",p->data);
p = p->prev;
}
printf("\n");
}
//销毁一个双向链表
void DestroyDoublelist(pDoulist list)
{
assert(list != NULL);
while( list->count > 0)
{
DeleteHeadDoublelist(list); //调用删除头结点的函数,采用循环的方式每次删除头结点
}
}
(测试)main.c
#include"DoubleList.h"
int main()
{
Doublelist list;
Doublelist *p = &list;
InitDoublelist(&list); //初始化链表
printf("count3 = %d\n",p->count);
for( int i = 0; i < 5; i++ )
{
InsertDoublelist(&list,i * 10 ,i); //插入节点函数
Show1(&list);//顺序输出结点数据函数
}
Show1(&list);//顺序输出结点数据函数
InsertTailDoublelist(&list,88);
InsertHeadDoublelist (&list,99);
Show2(&list);
Reverseshow(&list);//逆序输出结点数据函数
for( int i = 4; i > 0; i--)//删除前四个结点
{
DeleteDoublelist(&list,i);//删除结点函数
Show2(&list);//顺序输出结点数据函数
}
Show2(&list);//顺序输出结点数据函数
return 0;
}
输出结果: