解释,我们在单链表中,有了next指针,查找下一元素为O(1),而查找上一节点的话,则是O(n)。
所以为了克服单向性这一缺点,我们在单链表的每个节点中,在设置一个指向其前区节点的指针域。
#include "string.h"
#include "ctype.h"
#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 1000 /* 存储空间初始分配量 */
typedef int ElemType ;
typedef int status ;
typedef struct DulNode{
ElemType data;
struct DulNode * next;
struct DulNode * prior;
}DulNode,*DuLinkList;
//typedef struct DulNode* DuLinkList; 和上述表示方法一样
status InitList(DuLinkList * L){
(*L) =(DuLinkList) malloc(sizeof(DulNode));
if(*L == NULL){
return ERROR;
}else{
(*L)->next = NULL;
(*L)->prior = NULL;
return OK;
}
}
status EemptyList(DuLinkList L){
if(L->next == NULL){
return ERROR;
}else{
return OK;
}
}
status Inserthead(DuLinkList **L,ElemType e){
DuLinkList first;
first = (DuLinkList)malloc(sizeof(DulNode));
first->data = e;
//printf("%p\n",(*(*L)));
(*(*L))->next = first;
first->prior = (*(*L));
first->next = NULL;
return -1;
}
status InsertTail(DuLinkList *L,ElemType e){//从表尾插 //
DuLinkList rear;
rear = (DuLinkList)malloc(sizeof(DulNode));
rear->data = e;
(*L)->next = rear;
rear->prior = (*L);
rear->next = NULL;
return 1;
}
status ListInsert(DuLinkList *L , int i, ElemType e){//考虑没有节点和插入到第一个位置
if(!EemptyList(*L))
return Inserthead(&L,e);
DuLinkList p = (*L);
int j=1;
while(p && j<i ){
p = p->next;
j++;
}
if(!p||j>i){//用于判断i大于公共的节点数越界的情况和i=0的情况
return ERROR;
}
if(p->next == NULL){//最后一个位置的后一个位置
InsertTail(&p,e); //传p不用重新遍历
return -1;
}
DuLinkList q = (DuLinkList)malloc(sizeof(DulNode));
q->data = e;
q->next = p->next;
q->prior=p;
p->next->prior = q;
p->next = q;
}
status GetElem(DuLinkList L ,int i , ElemType *e){ //L指向头结点 L叫头指针
int j=1;
DuLinkList p = L->next;//指向第一个节点
while(p&&j<i){
j++;
p = p->next;
}
if(!p||j>i){
return ERROR;
}
*e = p->data;
return OK;
}
status DeleteList(DuLinkList * L , int i ,ElemType *e){//由于是双向链表没有必要再去找到i-1个位置
if(!EemptyList(*L))
return ERROR;
int j=1;
DuLinkList p = (*L)->next; //从第一个位置开始
while(p&&j<i){
j++;
p=p->next;
}
if(!p||j<i){
printf("dasdasd\n");
return ERROR;
}
*e = p->data;
if(p->next==NULL){ //删除最后一个元素
p->prior->next = NULL;
free(p);
return OK;
}
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
return OK;
}
int ListLength(DuLinkList L){
if(!EemptyList(L))
return 0;
int j=0;
DuLinkList p = L->next;
while(p){
j++;
p = p->next;
}
return j;
}
status FromHeadInsert(DuLinkList *L ,int n){
(*L) =(DuLinkList) malloc(sizeof(DulNode));
(*L)->next = NULL;
(*L)->prior = NULL;
int i;
srand(time(0));
DuLinkList q=NULL;//用于记录原第一个节点的位置
for(i=0;i<n;i++){
DuLinkList s;
s = (DuLinkList) malloc(sizeof(DulNode));
s->data = rand()%100+1;
s->prior = (*L);
s->next = q;
if(i!=0)
(*L)->next->prior = s;//除了第一次插入的节点外,以后每次插
//入都需要设置原来的节点的前一个指向新的节点
//q->prior = s 也可以
(*L)->next = s;
q=s;
}
return OK;
}
status FromTailInsert(DuLinkList *L ,int n){
(*L) =(DuLinkList) malloc(sizeof(DulNode));
(*L)->next = NULL;
(*L)->prior = NULL;
int i;
srand(time(0));
DuLinkList q=(*L);//用于记录原节点的位置
for(i=0;i<n;i++){
DuLinkList s;
s = (DuLinkList) malloc(sizeof(DulNode));
s->data = rand()%100+1;
s->prior = q;
s->next = NULL;
q->next = s;
q=s;
}
}
status ClearList(DuLinkList *L){
if(!EemptyList(*L))
return ERROR;
DuLinkList p=(*L)->next,q;
while(p){
q=p->next;
free(p);
p=q;
}
(*L)->next = NULL;
(*L)->prior = NULL;
return OK;
}
int LocateElem(DuLinkList L,ElemType e){
if(!EemptyList(L))
return ERROR;
DuLinkList p=L->next;
int i=1;
while(p){
if(p->data == e)
{
return i;
}
p=p->next;
i++;
}
return ERROR;
}
int main(){
DuLinkList node;
InitList(&node);
//判读是否为空
printf("%d\n",EemptyList(node));
ListInsert(&node,1,2);//从头插
printf("%p\n",node);
// printf("%d\n",node->next->data);
ListInsert(&node,1,5);
ListInsert(&node,2,7);
ListInsert(&node,2,9);
ListInsert(&node,5,19);//插入到最后一个位置的下一个
DuLinkList first,first1;
first = node->next;
while(first){
printf("%d\n",first->data);
first1 = first;
first= first->next;
}
printf("\n");
while(first1!=node){
printf("%d\n",first1->data);
first1= first1->prior;
}
printf("\n");
//得到元素
int value;
GetElem(node,5,&value);
printf("%d\n",value);
//删除元素
printf("\n");
printf("%d\n",DeleteList(&node,1,&value));
//printf("%d\n",value);
first = node->next;
while(first){
printf("%d\n",first->data);
first1 = first;
first= first->next;
}
printf("\n");
while(first1!=node){
printf("%d\n",first1->data);
first1= first1->prior;
}
printf("\n");
//计算长度
int chang = ListLength(node);
printf("%d\n",chang);
//头插法
printf("\n");
DuLinkList HeadInsert,test,test1;
FromHeadInsert(&HeadInsert,10);
test = HeadInsert->next;
while(test){
printf("%d\n",test->data);
test1 = test;
test= test->next;
}
printf("\n");
while(test1!=HeadInsert){
printf("%d\n",test1->data);
test1= test1->prior;
}
printf("\n");
//尾插法
DuLinkList TailInsert;
FromTailInsert(&TailInsert,3);
test = TailInsert->next;
while(test){
printf("%d\n",test->data);
test1 = test;
test= test->next;
}
printf("\n");
while(test1!=TailInsert){
printf("%d\n",test1->data);
test1= test1->prior;
}
printf("\n");
//清空链表
printf("%p\n",TailInsert);
ClearList(&TailInsert);
printf("%p\n",TailInsert);
//查找相等元素的位置
int result = LocateElem(node,19);
printf("%d\n",result);
return 0;
}