O(1)时间删除单向循环链表给定结点

来源:互联网 发布:私有云 软件 编辑:程序博客网 时间:2024/06/06 02:27

//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;}




0 0