相对于单向链表就是新增加一个指针域用来保存上一个结点的的地址
也没什么特别的,
在写的时候想了一下,头结点要不要用来存放数据,
第一种想法是作为普通结点一样用来存放数据,这样的麻烦是遍历问题,怎么才知道这个链表遍历完了,也就是说找不到遍历停止的条件,如果要解决的话可以增设一个静态变量 CNT 用来保存结点的个数,利用CNT就可以控制遍历,这样也有问题的,比如在遍历的时候没有遍历完而是在中途就控制其停止了,那么现在要进行插入操作,就根本找不到位置了,想解决的话也有方法的,不如增设一个局部变量保存遍历节点的个数,,,,
但是,这样做感觉很麻烦
第二种想法是不用头结点;
在头结点中的数据域内存放一个特殊的数据,作为标志头结点,在进行其他操作的时候都可以快速的回到头结点;
省去了很多不必要的麻烦,
把头结点作为初始化,添加作为一个独立的函数很方便,
下面是凭感觉写的,没有测试,提供一个思路和思想,如果有错望指正
/*
双向循环链表的设计
*/
typedef char Elem;
typedef struct Node
{
Elem data;
struct Node *lnext,*rnext; //左右指针
}*List;
List head= new struct Node; //头结点,不用来保存数据,用来保存标志
List pre = new struct Node; //保存当前操作结点的直接前驱
head->data='\0'; //头结点中保存的是一个空字符用来做标记
head->lnext=head->rnext=head; //初始化左右指针,回指
pre=head; //初始化pre
void Add(List pre,Elem c) //pre前一次添加后的最后一个结点
{
List p =new struct Node; //新增结点
p->data=c; //赋值
head->lnext=p; //头结点的右指针始终指向最后一个结点
pre->rnext=p; //将新增结点连接上
p->lnext=pre; //新增结点的左指针指向前驱结点
p->rnext=head; //新增结点的右指针指向头结点
pre=p; //这一步是保证pre存放的始终是新增结点的直接前驱
}