//O(1)时间删除单向循环链表给定结点(已知指向该结点的指针)
/*若是不带哨兵的单链表,删除非最后结点可以在O(1)完成。
但是,若删除的是最后结点,则必须修改最后结点的前驱的next为NULL,
故此时不得不得到p的前驱(需要O(n))。
单向循环链表则不一样了,每一个结点的next都非NULL(即都有后继)。
*/
//带哨兵的单向循环链表。NIL的next是头结点,尾结点的next是NIL
#include<stdio.h>
#include<stdlib.h>
typedef struct NODE{
char key;struct NODE* next;
}NODE;
NODE *NIL=NULL;
void insert(NODE* p)
{//插入到头结点
p->next=NIL->next;
NIL->next=p;
}
void delete(NODE* p)
{//把p下一结点next的值给p,然后删除next
if(!p) return ;
NODE* next=p->next;
p->key=next->key;
p->next=next->next;
if(next==NIL) NIL=p;//若p是最后结点,因为p->next=NIL,故NIL要指向p原来的内存空间
free(next);
}
NODE* search(char key)
{
NODE*p=NIL->next;NIL->key=key;
while(p->key!=key) p=p->next;
return p==NIL?NULL:p;
}
NODE* createnode(char key)
{
NODE*p=(NODE*)malloc(sizeof(NODE));
if(!p){
puts("memory exhausted.");exit(1);
}
p->key=key;
return p;
}
void traverse()
{
NODE*p;
for(p=NIL->next;p!=NIL;p=p->next)
putchar(p->key);
putchar('\n');
}
int main(void)
{
//初始化NIL链表
NIL=createnode('?');NIL->next=NIL;
insert(createnode('a'));
delete(search('a'));
traverse();
insert(createnode('b'));
insert(createnode('c'));
insert(createnode('d'));
insert(createnode('e'));
delete(search('e'));
traverse();
delete(search('b'));
delete(search('c'));
delete(search('b'));
//delete(search('d'));
//delete(search('b'));
traverse();
return 0;
}