双链表:
有时候以倒序扫描链表很方便。标准实现方法此时无能为力,然而解决解决方法却很简单,只要在数据结构上附加一个域,使他包含指向前一个指针即可。
双链表的实例可以直接拿上一遍博客的单链表来修改。当你把单链表很熟的时候,会发现双链表其实也挺简单的。
实例如下:
//dlinklist.h文件
#ifndef __DLINKLIST_H__
#define __DLINKLIST_H__
typedef struct dlinklistnode
{
struct dlinklistnode *next;
struct dlinklistnode *prev; //多了一个指向前一个节点的指针prev
int item; //自身的信息
}DLinkListNode; //数据节点
typedef struct dlinklist
{
DLinkListNode header;
int length; //链表的长度
}DLinkList; //头节点
DLinkList *DLinkList_Create();
void DLinkList_Destroy(DLinkList *list);
void DLinkList_Clear(DLinkList *list);
int DLinkList_Length(DLinkList *list);
int DLinkList_Insert(DLinkList *list, DLinkListNode *node, int pos);
DLinkListNode *DLinkList_Get(DLinkList *list,int pos);
DLinkListNode *DLinkList_Delete(DLinkList *list,int pos);
#endif //__DLINKLIST_H__
//dlinklist.c文件
#include <stdlib.h>
#include "dlinklist.h"
//创建
DLinkList *DLinkList_Create()
{
DLinkList *ret = NULL;
ret = malloc(sizeof(DLinkList));
if(ret!=NULL)
{
ret->length = 0;
ret->header.next = NULL;
ret->header.prev = NULL;
}
return ret;
}
//销毁
void DLinkList_Destroy(DLinkList *list)
{
free(list);
}
//清空
void DLinkList_Clear(DLinkList *list)
{
if(list!=NULL)
{
list->length =0;
list->header.next = NULL;
list->header.prev = NULL;
}
}
//长度
int DLinkList_Length(DLinkList *list)
{
int ret = -1;
if( list!=NULL )
{
ret = list->length;
}
return ret;
}
//插入
int DLinkList_Insert(DLinkList *list, DLinkListNode *node, int pos)
{
int ret = list!=NULL && node!=NULL && pos>=0;
if( ret )
{
int i;
DLinkListNode *cur = (DLinkListNode *)list;
DLinkListNode *next = NULL;
for(i=0;i<pos && cur->next!=NULL;i++)
{
cur = cur->next;
}
next = cur->next;
node->next = next;
if( cur != (DLinkListNode *)list )//判断是否插到第一个节点。
node->prev = cur;
else
node->prev == NULL;
if(next != NULL) //判断是否插到最后
next->prev = node;
cur->next = node;
list->length++;
}
return ret;
}
//获得
DLinkListNode *DLinkList_Get(DLinkList *list,int pos)
{
DLinkListNode *ret = NULL;
if( list!=NULL && (0<=pos && pos<list->length) )
{
int i;
DLinkListNode *cur = (DLinkListNode *)list;
for(i=0; i<pos; i++)
cur = cur->next;
ret = cur->next; //因为从0开始计数的,要第三个数,那么就是第二个数的next
}
return ret;
}
//删除
DLinkListNode *DLinkList_Delete(DLinkList *list,int pos)
{
DLinkListNode *ret = NULL;
if(list!=NULL && (0<=pos&&pos<list->length) )
{
int i;
DLinkListNode *cur = (DLinkListNode *)list;
DLinkListNode *next = NULL;
for(i=0; i<pos; i++)
cur = cur->next;
ret = cur->next; //cur->next就是我们要删除的节点
next = ret->next;
cur->next = next;
if( next !=NULL) //判断是否删除最后一个节点
{
if(cur == (DLinkListNode *)list) //判断删除的是不是第一个节点
{
next->prev = NULL;
}
else
{
next->prev = cur;
}
}
list->length--;
}
return ret;
}
//main.c文件
#include <stdio.h>
#include "dlinklist.h"
int main( void )
{
int i;
DLinkListNode *p = NULL;
DLinkListNode v1 = {NULL,NULL,1};
DLinkListNode v2 = {NULL,NULL,2};
DLinkListNode v3 = {NULL,NULL,3};
DLinkListNode v4 = {NULL,NULL,4};
DLinkList *list = DLinkList_Create(); //创建后返回创建好的头节点ret(指向结构体的指针)
DLinkList_Insert(list,&v1,0);
DLinkList_Insert(list,&v2,0);
DLinkList_Insert(list,&v3,0);
DLinkList_Insert(list,&v4,0);
for(i=0; i<DLinkList_Length(list);i++)
{
p = DLinkList_Get(list,i);
printf("%d ",p->item);
}
printf("\n");
DLinkList_Destroy(list);
}
//Makefile
cc :=gcc -g
main : main.o dlinklist.o
gcc $^ -o $@
.PHONY : main clean
clean:
rm -rf *.o main