/************************************************************************/
/* 数据结构:双向链表                                                                               */
/* 挑灯看剑-shuchangs@126.com 2010-10                                                             */
/* 云歌国际(Cloud Singers International) www.cocoral.com                          */
/************************************************************************/
//以上接上一版面 《数据结构:双向链表1》
 
/*
* 打印链表函数,输入参数为链表头元和打印标
* tag='H'正向打印,tag='T'反向打印)
*/
void NodePrint(NodeHead H, char tag)
{
       static Status NodeIsEmpty(NodeHead H);//函数原型
       NodePointer p = NULL;
       COUNT i = 1;
       COUNT n = H.len;
       printf("线性链表长度:%d\n", n);
       if (!NodeIsEmpty(H)) //如果线性链表非空
       {
              switch (tag)
              {
              case 'H':
                     p = H.head;
                     puts("正向打印结点信息:");
                     for (i = 1; i <= n; i++)
                     {
                            printf("Node[%d] = %d\n", i, p->data);
                            p = p->next;
                     }
                     break;
              case 'h':
                     p = H.head;
                     puts("正向打印结点信息:");
                     for (i = 1; i <= n; i++)
                     {
                            printf("Node[%d] = %d\n", i, p->data);
                            p = p->next;
                     }
                     break;
              case 'T':
                     p = H.tail;
                     puts("反向打印结点信息:");
                     for (i = n; i >= 1; i--)
                     {
                            printf("Node[%d] = %d\n", i, p->data);
                            p = p->prior;
                     }
                     break;
              case 't':
                     p = H.tail;
                     puts("反向打印结点信息:");
                     for (i = n; i >= 1; i--)
                     {
                            printf("Node[%d] = %d\n", i, p->data);
                            p = p->prior;
                     }
                     break;
              default:
                     puts("打印失败!");
                     break;
              }
       }
       else //如果线性链表为空表
       {
              puts("打印失败!线性链表为空表!");
       }
}
 
void autoList(NodeHead* H, int n)
{
       //自动生成n个结点的线性链表
       NodePointer p = H->head;
       int i = 1;
       for (; i <= n; i++)
       {
              NodeInsert(H, i, i * 2);
       }
       //NodePrint(*H,'H');
}
 
//删除线性链表中第i个位置结点,并用LNode型结点返回之
Status NodeDelete(NodeHead* H, int i, Node* N)
{
       Status status = ERROR;
       NodePointer p = NULL, q = NULL;
       COUNT j = 0, n = H->len;
       //判断是否是空表
       if (!NodeIsEmpty(*H))
       {
              if (i == 1)
              {
                     //如果i==1
                     p = H->head; //头结点(第一个结点)
                     q = p->next; //次头结点
                     H->head = q;   //修改后继结点
                     q->prior = NULL; //修改前驱结点
 
                     N->data = p->data; //返回结点信息
                     N->prior = p->prior;
                     N->next = p->next;
 
                     free(p);
                     H->len -= 1; //长度减1
                     status = OK;
                     puts("删除成功!");
              }
              else if (i >= 2 && i <= H->len - 1)
              {
                     //如果i在区间2-LEN-1之间
                     //先查找i-1个结点
                     for (p = H->head,j = 2; j <= i - 1; j++)
                            p = p->next; //p前进一位
                     //进行删除操作
                     q = p->next; //指向删除结点
                     p->next = q->next;
                     q->next->prior = p;
 
                     N->data = q->data; //返回结点信息
                     N->next = q->next;
                     N->prior = q->prior;
 
                     free(q);
                     H->len -= 1; //长度减1
                     status = OK;
                     puts("删除成功!");
              }
              else if (i == H->len)
              {
                     //如果删除位置是最后一个结点
                     q = H->tail; //尾结点
                     p = q->prior; //次尾结点
 
                     H->tail = p;
                     p->next = NULL;
 
                     N->data = q->data; //返回结点信息
                     N->next = q->next;
                     N->prior = q->prior;
 
                     H->len -= 1; //长度减1
                     status = OK;
                     free(q);
                     puts("删除成功!");
              }
              else
              {
                           status = ERROR;
                     printf("删除失败!链表区间为:1-%d,删除位置为:%d 越界!\n",
                            H->len, i);
              }
       }
       else
       {
              status = ERROR;
              puts("删除失败!链表为空表!");
       }
 
       return status;
}