双向链表
优点:可以从任一节点向前向后查找
缺点:多分配一个指针存储空间
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* 双向链表
* 优点:
* 可以从任一节点向前向后查找
* 缺点:
* 多分配一个指针存储空间
* @2019-09-22
*/
#define LIST_SIZE 30
#define LIST_INCREMENT 10
typedef char * ElementType;
typedef struct DuLnode{
ElementType data;
struct DuLnode *prior;
struct DuLnode *next;
}DuLnode, *DuLnPtr;
typedef struct{
DuLnode *head; //带头指针的双向链表
int size;
}DLinkList;
typedef enum{
false,
true
}bool;
bool initList(DLinkList *list)
{
list->head = (DuLnode *)malloc(sizeof(DuLnode)*LIST_SIZE);
if(NULL == list->head)
{
printf("Memory allocated Failure!\n");
exit(-1);
}
DuLnPtr head = list->head;
list->size = 0;
head->prior = NULL;
head->next = NULL;
return true;
}
bool isFull(DLinkList *list)
{
bool flag = (list->size >= LIST_SIZE) ? true : false;
return flag;
}
bool isEmpty(DLinkList *list)
{
return (list->size == 0) ? true : false;
}
/**
* 双向链表 在第i个位置之前插入元素e
* @param list
* @param i
* @param e
* @return
*/
bool insert(DLinkList *list, int i, ElementType e)
{
if(i > list->size -1)
{
printf("the Index of list i: %d is overflow!\n");
return false;
}
if(isEmpty(list))
{
list->head->data = e;
}
else
{
DuLnPtr p = list->head;
int j=0;
while(NULL != p && j < i-1)
{
p = p->next;
j++;
}
DuLnPtr newPtr = (DuLnode *)malloc(sizeof(DuLnode));
if(NULL == newPtr)
{
printf("Memory allocate Failure!\n");
exit(-1);
}
newPtr->data = e;
p->next->prior = newPtr;
newPtr->next = p->next;
p->next = newPtr;
newPtr->prior = p;
}
list->size++;
if(isFull(list))
{
list->head = (DuLnode *)realloc(list->head,
(list->size + LIST_INCREMENT)*sizeof(ElementType));
if(NULL == list->head)
{
printf("Memory relloc Failure!\n");
exit(-1);
}
}
return true;
}
/**
* 双向链表删除第i个元素
* @param list
* @param i
* @return
*/
bool delete(DLinkList *list, int i)
{
if(isEmpty(list))
{
printf("List is empty!\n");
return false;
}
if(i > list->size -1)
{
printf("the Index of list i: %d is overflow!\n");
return false;
}
DuLnPtr p = list->head;
DuLnPtr q;
int j = 0;
while(NULL != p && j < i-1)
{
p = p->next;
j++;
}
//q:待删除的节点
q = p->next;
ElementType e = q->data;
p->next = q->next;
q->next->prior = p;
q->next = NULL;
q->prior = NULL;
free(q);
printf("No: %d Element value is %s has deleted!\n",i,e);
return true;
}
/**
* 在链表尾部顺序插入一个元素
* @param list
* @param e
* @return
*/
bool append(DLinkList *list, ElementType e)
{
DuLnode *p = list->head;
if(isEmpty(list))
{
p->data = e;
}
else
{
DuLnPtr q;
while(NULL != p)
{
q = p;
p = p->next;
}
DuLnPtr nodePtr = (DuLnPtr)malloc(sizeof(DuLnode));
if(NULL == nodePtr)
{
printf("Memory allocated Failure!\n");
exit(-1);
}
nodePtr->data = e;
q->next = nodePtr;
nodePtr->prior = q;
nodePtr->next = NULL;
}
list->size++;
if(isFull(list))
{
list->head = (DuLnode *)realloc(list->head,
(list->size + LIST_INCREMENT)*sizeof(ElementType));
if(NULL == list->head)
{
printf("Memory relloc Failure!\n");
exit(-1);
}
// list->size += LIST_INCREMENT;
}
return true;
}
/**
* 从当前节点node向前向后查找并符合条件节点的地址
* 返回节点地址的拼接字符串,逗号分隔
* @param list
* @param nodePtr
* @param e
* @return
*/
DuLnPtr find(DLinkList *list, ElementType e)
{
DuLnPtr p = NULL;
if(isEmpty(list))
{
printf("list is Empty!\n");
return NULL;
}
p = list->head;
bool flag = false;
while(NULL !=p)
{
if(p->data == e)
{
flag = true;
break;
}
p = p->next;
}
if(!flag)
{
printf("Not Found Element: %s.\n", e);
return NULL;
}
printf("Element %s Node ptr is: %p.\n", e, p);
return p;
}
/**
* 打印
* @param list
*/
void traverse(DLinkList *list)
{
if(NULL == list)
{
printf("list is null!\n");
exit(-1);
}
if(isEmpty(list))
{
printf("list is empty!\n");
return;
}
DuLnode *p = list->head;
while(NULL !=p){
printf("Element value is: %s.\n",p->data);
p = p->next;
}
}
int main() {
DLinkList *list = (DLinkList *)malloc(sizeof(DLinkList));
if(NULL == list)
{
printf("Memory allocated Failure!\n");
exit(-1);
}
initList(list);
append(list, "zhao");
append(list, "qian");
append(list, "sun");
append(list, "li");
// insert(list, 2, "sun");
delete(list,2);
traverse(list);
printf("done!\n");
return 0;
}