首先当然得了解单向链表了
首先,表中的各个元素称作“结点”。双向链表的结点时结构体,有数据本体,指向前一元素的指针prev以及指向后一元素的指针next组成。这些结构体通过指针构成一个链表,就形成了双向链表。
struct node{ int key; node *prev,*next;//注意不是node *prev,next };
另外,在表头设置一个特殊节点可以简化链表的实现,将这个结点称为“头节点”,头节点中不包括实际数据,但它可以让我们更轻松地对链表做更改。
init函数用于初始化链表。它会生成一个NIL节点作为链表的头节点,然后让prev和next都指向这个头节点,从而创建一个空表。
node *nil; void init() { nil=(node*)malloc(sizeof(node)); nil->next=nil; nil->prev=nil; }
然后就是很重要的插入元素。
void insert(int key) { node *x=(node*)malloc(sizeof(node)); x->key=key; x->next=nil->next; nil->next->prev=x; nil->next=x; x->prev=nil; }
listsearch函数用于搜索元素,它可以在链表中寻找包含指定键值的结点,并返回其指针,假设cur为指向当前位置结点的指针,那么只要从头节点的next所指的结点,即链表开头的元素逐个进行cur=cur->next,即可逐一访问每个结点。
node* listsearch(int key) { node *cur=nil->next; while(cur!=nil&&cur->key!=key){ cur=cur->next; } return cur; }
deletenode函数删除指定结点t。
void deletenode(node *t) { if(t==nil){ return ; } t->prev->next=t->next;//修改前面的指向 t->next->prev=t->prev;//修改后面的指向 free(t); } void deletefirst() { deletefirst(nil->next); } void deletelast() { deletenode(nil->prev); } void deletekey(int key) { deletekey(listsearch(key)); }
deletelastfirst函数,deletelast函数分别用于删除头节点next,prev所指向的结点,deletekey函数可以删除包含指定key的结点,它可以先通过listsearch函数搜索出与key一致的结点t,然后再使用deletenode(t)删除该节点。
整体运用一下:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; struct node{ int key; node *prev,*next; }; node *nil; void init() { nil=(node*)malloc(sizeof(node)); nil->next=nil; nil->prev=nil; } void insert(int key) { node *x=(node*)malloc(sizeof(node)); x->key=key; x->next=nil->next; nil->next->prev=x; nil->next=x; x->prev=nil; } void deleteNode(node*t) { if(t==nil){ return ; } t->prev->next=t->next; t->next->prev=t->prev; free(t); } void deleteFirst() { deleteNode(nil->next); } void deleteLast() { deleteNode(nil->prev); } node* listSearch(int key) { node *cur=nil->next; while(cur!=nil&&cur->key!=key){ cur=cur->next; } return cur; } void deleteKey(int key) { deleteNode(listSearch(key)); } void printList() { node*cur=nil->next; int isf=0; while(1){ if(cur==nil){ break; } if(isf++>0){ printf(" "); } printf("%d",cur->key); cur=cur->next; } printf("\n"); } int main() { int n,key; char com[20]; scanf("%d",&n); init(); for(int i=0;i<n;i++){ scanf("%s%d",com,&key); if(com[0]=='i'){ insert(key); }else if(com[0]=='d'){ if(strlen(com)>=6){ if(com[6]=='F'){ deleteFirst(); }else if(com[6]=='L'){ deleteLast(); }else{ deleteKey(key); } } } } printList(); return 0; } /* 7 insert 5 insert 2 insert 3 insert 1 delete 3 insert 6 delete 5 */