双链表与单链表的操作在很多地方都能用到。
循环链表的话,特殊应用也能用到,既可以用单链表实现循环列表,也能用双链表实现循环列表,用单链表节省存储空间,但是运算逻辑相对
双链表要复杂,这就是通常说的以时间换空间。 单对时间要求严格时候也可:以空间换时间。
循环列表的代码不打算在园子里贴出来了,实现过程中需要注意的是:虽然头节点在建立循环链表之后,任何一个都可以看成是头节点,但是
还是以创建时分配的第一个节点为宜,因为这样不会随时随地的找头节点,同时要注意的是:单节点的时候,需要自己指向自己以符合循环链表的
定义,这个容易忽略。
下面是双链表的代码,运行测试结果在代码下面:
/* 本程序用来测试线性存储结构:链表*/#include#include //**************************************************0// 定义双链表数据结构struct dbllink{ char data; struct dbllink* preNode; struct dbllink* postNode;};typedef struct dbllink DBLLINK;typedef DBLLINK* PDBLLINK;//**************************************************1//**************************************************0// 定义BOOL数据类型typedef enum {FALSE,TRUE} BOOL ;//**************************************************1//**************************************************0// 定义申请存储空间宏#define MALLOC(pNode,type,size) if(NULL==\ (pNode=(type *)malloc(size*sizeof(type))))\{\ return FALSE;\}//**************************************************1//**************************************************0// 定义申请表头宏#define MALLOCH(pNode,type,size) if(NULL==\ (pNode=(type *)malloc(size*sizeof(type))))\{\ return NULL;\}else\{\ pNode->data='\0';\ pNode->preNode=NULL;\ pNode->postNode=NULL;\ return pNode;\}//**************************************************1PDBLLINK CreateDblLink(void);BOOL InitDblLink(PDBLLINK head,char element[]);void EchoDblLink(PDBLLINK head);PDBLLINK GetDblLinkEnd(PDBLLINK head);PDBLLINK GetDblLinkEnd(PDBLLINK head);BOOL AppendDblLink(PDBLLINK head,char element);PDBLLINK SearchDblLink(PDBLLINK head,char element);BOOL DenodeDblLink(PDBLLINK head,char element);BOOL InsertDblLink(PDBLLINK head,char elePos,char element);int main(int argc,char* argv[]){ PDBLLINK head; head=CreateDblLink(); if(head) puts("Yes."); if(InitDblLink(head,"hello world")) EchoDblLink(head); AppendDblLink(head,'A'); EchoDblLink(head); if(SearchDblLink(head,'A')) puts("Yes"); else puts("No"); if(DenodeDblLink(head,'l')) EchoDblLink(head); if(InsertDblLink(head,'l','l')) EchoDblLink(head); getchar(); getchar(); return 0;}//**************************************************0/*函数功能: 创建双链表表头函数原型 PDBLLINK CreateDblLink(void)函数参数: 无返回值: 创建成功返回表头指针,否则返回NULL异常 无*/PDBLLINK CreateDblLink(void){ PDBLLINK head; MALLOCH(head,DBLLINK,1);}//**************************************************1//**************************************************0/*函数功能: 初始化双链表函数原型: BOOL InitDblLink(PDBLLINK head,char element[])函数参数: PDBLLINK head: 链表头指针 char element[]:初始化字符串返回值: 如果初始化成功,返回TRUE,否则返回FALSE异常: 无*/BOOL InitDblLink(PDBLLINK head,char element[]){ PDBLLINK temp, end; int i; if(!head) { return FALSE; } end=head; for(i=0;element[i]!=0;i++) { MALLOC(temp,DBLLINK,1); temp->data='\0'; temp->postNode =NULL; temp->preNode=end; end->data=element[i]; end->postNode =temp; end=end->postNode ; } return TRUE;}//**************************************************1//**************************************************0/*函数功能: 打印链表函数原型: void EchoDblLink(PDBLLINK head)函数参数: PDBLLINK head:链表头指针返回值: 无异常: 无*/void EchoDblLink(PDBLLINK head){ PDBLLINK temp; if(temp=head) { while(temp->postNode) { printf("%c",temp->data ); temp=temp->postNode ; } putchar('\n'); return ; } else { return ; }}//**************************************************1//**************************************************0/*函数功能: 获取最后的节点函数原型: PDBLLINK GetDblLinkEnd(PDBLLINK head)函数参数: PDBLLINK head:链表头指针返回值: 如果获取成功,则返回链表尾节点指针,否则返回NULL异常: 无*/PDBLLINK GetDblLinkEnd(PDBLLINK head){ PDBLLINK temp; if(!head) { return NULL; } if(head->postNode) { temp=head; while(temp->postNode) { temp=temp->postNode; } return temp; } else { //仅有头指针 return head; }}//**************************************************1//**************************************************0/*函数功能: 在链表尾增加节点函数原型: BOOL AppendDblLink(PDBLLINK head,char element)函数参数: PDBLLINK head:链表头指针 char element: 要插入的字符返回值: 如果增加成功,返回TRUE;否则返回FALSE异常: 无*/BOOL AppendDblLink(PDBLLINK head,char element){ PDBLLINK end, NewNode; if(head) { end=GetDblLinkEnd(head); MALLOC(NewNode,DBLLINK,1); NewNode->data='\0'; NewNode->postNode=NULL; NewNode->preNode =end; end->data=element; end->postNode=NewNode; return TRUE; } else { return FALSE; }}//**************************************************1//**************************************************0/*函数功能: 查找指定元素函数原型: PDBLLINK SearchDblLink(PDBLLINK head,char element)函数参数: PDBLLINK head:链表头指针 char element: 要查找的字符返回值: 如果增加成功,返回元素所在的节点指针;否则返回NULL异常: 无*/PDBLLINK SearchDblLink(PDBLLINK head,char element){ PDBLLINK temp; if(!head) { return NULL; } else { temp=head; while(temp->postNode) { if(temp->data ==element) return temp; temp=temp->postNode ; } //如果遍历完毕,还没有返回,则查找失败 return NULL; }}//**************************************************1//**************************************************0/*函数功能: 删除指定字符所在的节点函数原型: BOOL DenodeDblLink(PDBLLINK head,char element)函数参数: PDBLLINK head:链表头指针 char element: 指定的字符返回值: 如果删除成功,返回TRUE,否则返回FALSE;异常: 无*/BOOL DenodeDblLink(PDBLLINK head,char element){ PDBLLINK temp, DeNode; if(NULL==head || head->postNode == NULL) { return FALSE; } temp=SearchDblLink(head,element); if(temp==head) { DeNode=head; head->postNode->preNode=NULL; head=head->postNode=NULL; DeNode->postNode=NULL; return TRUE; } else { temp->preNode->postNode =temp->postNode; temp->postNode->preNode=temp->preNode; free(temp); return TRUE; }}//**************************************************1//**************************************************0/*函数功能: 增加节点 1、如果指定的元素存在,则在指定元素之后增加 2、如果指定的元素不存在,则在最后增加函数原型: BOOL InsertDblLink(PDBLLINK head,char element)函数参数: PDBLLINK head:链表头指针 char elePos:指定的字符 char element: 要插入的字符返回值: 如果增加成功,返回TRUE,否则返回FALSE;异常: 无*/BOOL InsertDblLink(PDBLLINK head,char elePos,char element){ PDBLLINK temp, NewNode; if(NULL==head ) { return FALSE; } //如果仅有头节点,则必须插入到头节点之后 if(head->postNode == NULL) { MALLOC(NewNode,DBLLINK,1); NewNode->data='\0'; NewNode->postNode=NULL; NewNode->preNode=head; head->data=element; head->postNode=NewNode; return TRUE; } temp=SearchDblLink(head,element); MALLOC(NewNode,DBLLINK,1); NewNode->data =element; NewNode->postNode =temp->postNode; NewNode->preNode=temp; temp->postNode=NewNode; return TRUE;}//**************************************************1
上面的代码没有写销毁双链表的代码。