//双链循环线性表的表示与实现
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int status;
typedef int elemtype;
typedef struct node {
    elemtype data;
    struct node *prior;
    struct node *next;
} node, *linklist;

//初始化双链循环线性表
void initlist(linklist &l){
  l=(linklist)malloc(sizeof(node));
  l->next=l->prior=l;
}

//获取双链循环线性表中的元素
node * GetElemP_Dul(linklist l, int i) {
     linklist p = l;
    if (i < 1)   //非法i值
        return NULL;
    if (p->next == l) //空双向循环链表
        return l;
    p = l->next;
    int j = 1;   //初始化, p指向第一个结点, j为计数器
    while(p != l && j < i) {  //顺指针向后查找, 直到p指向第i个元素或p指向头结点
        p = p->next;
         ++j;
    }
    return p;
}
status listinsert(linklist &l, int i, elemtype e) {
    //在带头结点的双链循环线性表L中第i个位置之前插入元素e
    //i的合法值为1 <= i <= 表长 + 1
    linklist p = NULL;
    if (!(p = GetElemP_Dul(l, i)))//在p节点前插入s
        return ERROR;
    linklist s = (linklist)malloc(sizeof(node));
    s->data = e;
    s->prior = p->prior; p->prior->next = s;
    s->next = p;         p->prior = s;
    return OK;
}

//删除元素
status ListDelete_DuL(linklist &L, int i, elemtype &e) {
    //在带头结点的双链线性表L中, 删除第i个元素, 并由e返回其值
    //i的合法值为1 <= i <= 表长
    struct node *p = NULL;
    if (!(p = GetElemP_Dul(L, i)) || L == GetElemP_Dul(L, i))
        return ERROR;
    e = p->data;
    p->prior->next = p->next;
    p->next->prior = p->prior;
    free(p); return OK;
}

//遍历线性表
status ListTraverse_DuL(linklist L, status (*Visit)(elemtype)) {
    printf("traverse list: ");
    struct node *p = L->next; //略过头结点
    while (p != L) {
        Visit(p->data);
        p = p->next;
    }
    return OK;
}
//访问线性表中的元素
status Visit(elemtype e){
    printf("%d ", e);
    return OK;
}

//测试函数
int  main(){
    linklist l;
     elemtype e;
    initlist(l);
    linklist p=l;
    for(int i=1;i<=10;i++)
    listinsert(l,i,i);

    ListTraverse_DuL(l, Visit);//遍历链表麻烦方法

          p=p->next;//遍历线性表简单方法
          while(p!=l){
          printf("%d ",p->data);
          p=p->next;
         }//end
}