双向链表——基于C语言

最近复习了C语言的相关知识,实现了数据结构里面的双向链表。

下面是Main.c文件:

#include "DualLinkList.h"
#include <stdio.h>

int main()
{
 	DualLinkList *list = DualLinkListCreate();
 
 	if(list != NULL)
 	{ 
  		int i = 0;
  		printf("此时双向链表长度为:%d\n", DualLinkListLength(list));
  
  		printf("插入状态:%d\n", DualLinkListInsert(list, 0, 0));
  		printf("插入状态:%d\n", DualLinkListInsert(list, 1, 1));
  		printf("插入状态:%d\n", DualLinkListInsert(list, 2, 2));
  		printf("插入状态:%d\n", DualLinkListInsert(list, 3, 3));
  		printf("插入状态:%d\n", DualLinkListInsert(list, 9, 4));
  
  		printf("此时双向链表长度为:%d\n", DualLinkListLength(list));
  
  		printf("开始打印链表:\n");
  		for(DualLinkListMove(list, 0); !DualLinkListEnd(list); DualLinkListNext(list), i++)
  		{
   			printf("data[%d] = %d\n", i, DualLinkListCurrent(list));
 		}
  
  		printf("开始打印链表:\n");
  		i = 0;
  		for(DualLinkListMove(list, DualLinkListLength(list) - 1); !DualLinkListEnd(list); DualLinkListPre(list), i++)
  		{
   			printf("data[%d] = %d\n", i, DualLinkListCurrent(list));
  		}
  
  		DualLinkListDelete(list, 0, NULL); 
  		DualLinkListDelete(list, 0, NULL);
  
  		printf("此时双向链表长度为:%d\n", DualLinkListLength(list));
  
  		printf("删除状态:%d\n", DualLinkListDelete(list, 1, NULL)); 
  		printf("此时双向链表长度为:%d\n", DualLinkListLength(list));
  
  		list = DualLinkListDestroy(list);
 	}	

	return 0;
}

下面是DualLinkList.h文件:

#ifndef __DUALLINKLIST_H__
#define __DUALLINKLIST_H__

typedef int DataType;

#define deBug() printf("File = %s\nLine = %d\n", __FILE__, __LINE__)

#include <stdio.h>
#include <stdlib.h>

#ifndef __cplusplus
 	typedef int Bool;
 	#define true 1
 	#define false 0
#else
 	typedef bool Bool;
#endif

#define STRUCT(type)  typedef struct _struct##type type; \
      struct _struct##type

#define MALLOC(type, size)  (type*)malloc(sizeof(type) * size)
#define FREE(p)    (free(p), p = NULL)

STRUCT(DLLNode)
{
 	DataType data;
 	DLLNode *pre;
 	DLLNode *next;
};

STRUCT(DualLinkList)
{
 	DLLNode *next;
 	DLLNode *m_current;
 	int len;
};

DualLinkList* DualLinkListCreate(void);
DualLinkList* DualLinkListDestroy(DualLinkList *list);
int DualLinkListLength(DualLinkList *list);
Bool DualLinkListInsert(DualLinkList *list, int i, DataType data);
Bool DualLinkListDelete(DualLinkList *list, int i, DataType *data);
int DualLinkListFind(DualLinkList *list, DataType data); 
Bool DualLinkListSet(DualLinkList *list, int i, DataType data);
Bool DualLinkListGet(DualLinkList *list, int i, DataType *data);
DLLNode* DualLinkListMove(DualLinkList *list, int i);
Bool DualLinkListEnd(DualLinkList *list);
void DualLinkListNext(DualLinkList *list);
void DualLinkListPre(DualLinkList *list);
DataType DualLinkListCurrent(DualLinkList *list);

#endif

下面是DualLinkList.c文件:

#include <stdio.h>
#include "DualLinkList.h"

DualLinkList* DualLinkListCreate(void)  //O(1)
{
 	DualLinkList *list = MALLOC(DualLinkList, 1);
 
 	if(list != NULL)
 	{
  		list->next = NULL;
  		list->m_current = NULL;
  		list->len = 0;
 	}
 
 	return list;
}

DualLinkList* DualLinkListDestroy(DualLinkList *list)  //O(n)
{ 
 	if(list != NULL)
 	{
  		while(list->next != NULL)
  		{
   			DualLinkListDelete(list, 0, NULL);
  		}
   
  		FREE(list);  
 	}
	
	return NULL;
}

int DualLinkListLength(DualLinkList *list) //O(1)
{ 
 	return (list != NULL) ? list->len : -1;
}

Bool DualLinkListInsert(DualLinkList *list, int i, DataType data)  //O(n)
{
 	Bool ret = (i >= 0) && (i <= DualLinkListLength(list));
 
 	if(ret)
 	{
  		DLLNode *node = MALLOC(DLLNode, 1);
  
  		if(node)
 	 	{
   			node->data = data;
   
   			if(0 == i)
   			{
    				node->next = list->next;
    				node->pre = NULL;
    				if(list->next != NULL) list->next->pre = node;    
    				list->next = node;
   			}
   			else
   			{
    				DLLNode *pre = DualLinkListMove(list, i - 1);
    
    				node->next = pre->next;
    				node->pre  = pre;
    
    				if(pre->next != NULL) pre->next->pre = node;
    				pre->next = node;
   			}
   
   			list->len++;
  		}
  		else
  		{
   			ret = false;
  		}
 	}
 
 	return ret;
}

Bool DualLinkListDelete(DualLinkList *list, int i, DataType *data) //O(n)
{
 	Bool ret = (i >= 0) && (i < DualLinkListLength(list));
 
 	if(ret)
 	{
  		DLLNode *node = list->next;
  
  		if(0 == i)
  		{
   			if(data) *data = node->data;
   
   			list->next = node->next;
   			if(node->next != NULL) node->next->pre = NULL;
  		}
  		else
  		{
   			DLLNode *pre = DualLinkListMove(list, i - 1);
   
   			node = pre->next;
   
   			if(data) *data = node->data;
   
   			pre->next = node->next;    
   			if(node->next != NULL) node->next->pre = pre;
  		}
  
  		free(node);
  
  		list->len--;
 	}
 
 	return ret;
}

Bool DualLinkListSet(DualLinkList *list, int i, DataType data) //O(n)
{
 	return ((i >= 0) && (i < DualLinkListLength(list))) ? (DualLinkListMove(list, i)->data = data, true) : false; 
}

Bool DualLinkListGet(DualLinkList *list, int i, DataType *data) //O(n)
{
 	return ((data != NULL) && (i >= 0) && (i < DualLinkListLength(list))) ? (*data = DualLinkListMove(list, i)->data, true) : false;
}

//以下五个函数配合使用以遍历双向链表,时间复杂度为O(n)
DLLNode* DualLinkListMove(DualLinkList *list, int i)
{
 	DLLNode *ret = NULL;
 
 	list->m_current = NULL;
 
 	if((list != NULL) && (i >= 0) && (i < DualLinkListLength(list)))
 	{  
 	 	DLLNode *node = list->next;
  
  		if(node != NULL)
  		{
   			int j;
   
   			for(j = 0; j < i; j++)
   			{
    				node = node->next; 
   			}
   
   			ret = node;
   			list->m_current = node;    
  		} 
 	}
 
 	return ret;
}

Bool DualLinkListEnd(DualLinkList *list)
{
 	return (list != NULL) ? (list->m_current == NULL) : false;
}

void DualLinkListNext(DualLinkList *list)
{
 	if((list != NULL) && (list->m_current != NULL))
 	{
  		list->m_current = list->m_current->next; 
 	} 
}

void DualLinkListPre(DualLinkList *list)
{
 	if((list != NULL) && (list->m_current != NULL))
 	{
  		list->m_current = list->m_current->pre; 
 	}  
}

DataType DualLinkListCurrent(DualLinkList *list)
{
 	return ((list != NULL) && (list->m_current != NULL)) ? list->m_current->data : (DataType)0;
}

int DualLinkListFind(DualLinkList *list, DataType data) //O(n)
{
 	int ret = -1;  
 
 	if(list)
 	{
  		int i = 0;
  
  		for(DualLinkListMove(list, 0); !DualLinkListEnd(list); DualLinkListNext(list), i++)
  		{
   			if(DualLinkListCurrent(list) == data)
   			{
    				ret = i;
   	 			break;
   			}
  		}  
 	}
 
 	return ret;
}

下面是运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值