C語言實現雙向鏈表的基本操作

#include<stdio.h>
#include<stdlib.h>

#define TRUE 1
#define OK 1
#define FALSE 0
#define ERROR 0
#define NULL 0
#define OVERFLOW 0

typedef int ElemType;
typedef int Status;

typedef struct DuLNode
{ ElemType data;
  DuLNode *prior,*next;
}DuLNode,*DuLinkList;

//函數聲明
void InitList(DuLinkList &L);//初始化鏈表
void ClearList(DuLinkList L);//清空表
void DestroyList(DuLinkList &L);//銷燬雙向鏈表
Status ListEmpty(DuLinkList L);//判斷表是否爲空
int ListLength(DuLinkList L);//判斷表的長度
Status GetElem(DuLinkList L,int i,ElemType &e);//返回第i個元素的值
int LocateElem(DuLinkList L,ElemType e,Status(*compare)(ElemType,ElemType));//返回L中第1個與e滿足關係compare()的數據元素的位序
Status PriorElem(DuLinkList L,ElemType cur_e,ElemType &pre_e);//前驅判斷
Status NextElem(DuLinkList L,ElemType cur_e,ElemType &next_e);//後繼判斷
DuLinkList GetElem(DuLinkList L,int i);//返回第i個元素的地址
Status ListInsert(DuLinkList L,int i,ElemType e);//在表的第i個位置之前插入元素e
Status ListDelete(DuLinkList L,ElemType &e);//刪除表中第i個元素
void ListTraverse(DuLinkList L,void(*visit)(ElemType));//正序對每個元素調用函數visit()
void ListTraverseBack(DuLinkList L,void(*visit)(ElemType));//逆序對每個元素調用函數visit()
void print(ElemType e);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

函數文件b02_7.cpp

#include<stdio.h>
#include"c2_4.h"

void InitList(DuLinkList &L)
{//產生空間的雙向循環鏈表
 L=(DuLinkList)malloc(sizeof(DuLNode));
 if(L)
  L->next=L->prior=L;
 else
  exit(OVERFLOW);
}

void ClearList(DuLinkList L)
{ //清空鏈表
 DuLinkList p=L->next;//p指向第一個結點
 while(p!=L)
 {  p=p->next;
 free(p->prior);
 }
 L->next=L->prior=L;//頭結點的兩個指針域指向其身
 
}
void DestroyList(DuLinkList &L)
{ ClearList(L);//將L清空
  free(L);
  L=NULL;
}
Status ListEmpty(DuLinkList L)
{ //判斷表是否爲空
 if(L->next==L&&L->prior==L)
    return TRUE;
 else
  return FALSE;
}
int ListLength(DuLinkList L)
{ //返回表的長度
 int i=0;
 DuLinkList p=L->next;//p指向第一個結點
 while(p!=L)
 { i++;
  p=p->next;
 }
return i;
}

Status GetElem(DuLinkList L,int i,ElemType &e)
{ //當第i個元素存在,將值賦給e
 int j=1;
 DuLinkList p=L->next;//p指向第一個結點
 while(p!=L&&j<i)//順指針向後查找,直到p指向第i個元素
 { j++;
  p=p->next;
 }
 if(p==L||j>i)
  return ERROR;
 e=p->data;
 return OK;
}
int LocateElem(DuLinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
{ //返回表中第1個與e滿足關係compare()的數據元素的位序
 int i=0;
 DuLinkList p=L->next;
 while(p!=L)//p未指向頭結點
 { i++;//計數器加1
 if(compare(p->data,e))//找到這樣的元素
  return i;
  p=p->next;
 }
 return 0;
}
Status PriorElem(DuLinkList L,ElemType cur_e,ElemType &pre_e)
{ DuLinkList p=L->next->next;//p指向第2個元素
 while(p!=L)
 { if(p->data==cur_e)//p指向值爲cur_e的結點
 {pre_e=p->prior->data;//將p的前驅結點的值賦給
 return OK;
 }
 
 p=p->next;
 }
 return ERROR;
}

Status NextElem(DuLinkList L,ElemType cur_e,ElemType &next_e)
{//返回後繼
 DuLinkList p=L->next->next;//p指向第二個元素
 while(p!=L)
 { if(p->prior ->data==cur_e)//p所指結點的前驅指向cur_e
 { next_e=p->data;//將p所指結點的值賦給next_e
   return OK;
 }
 p=p->next;
 }
 return ERROR;
}
DuLinkList GetElemP(DuLinkList L,int i)
{//在雙向鏈表中返回第i個元素的地址
 int j;
 DuLinkList p=L;//p指向頭結點
 if(i<0||i>ListLength(L))
  return NULL;
 for(j=1;j<=i;j++)//p指向第i個結點
  p=p->next;//p指向下一個結點
 return p;
}
Status ListInsert(DuLinkList L,int i,ElemType e)
{ //在鏈表第i個位置上插入元素
 DuLinkList p,s;
 if(i<1||i>ListLength(L)+1)
  return ERROR;
 p=GetElemP(L,i-1);//在L中確定第i個結點前驅的位置指針p
 if(!p) return ERROR;

 s=(DuLinkList)malloc(sizeof(DuLNode));//生成新結點
 if(!s) return ERROR;

 s->data=e;//將e賦給新的結點
 s->prior=p;//新結點的前驅爲第i-1個結點
 s->next=p->next;//新結點的後繼爲第i個結點
 p->next->prior=s;//第i個結點的前驅指向新結點
 p->next=s;//第i-1個結點的後繼指向新結點
 return OK;
}

Status ListDelete(DuLinkList L,ElemType &e)
{  //刪除第i個結點
 DuLinkList p;
 int i;
 if(i<1)
  return ERROR;
 p=GetElemP(L,i);//在L中確定第i個元素的位置指針
 if(!p) return ERROR;
 e=p->data;//把第i個結點的元素的值賦給e
 p->prior->next=p->next;//第原i-1個結點的後繼指向原第i+1個結點
 p->next->prior=p->prior;//第原i+1個結點的前驅指向原第i-1個結點
 free(p);
 return OK;
}

void ListTraverse(DuLinkList L,void(*visit)(ElemType))
{//由雙向循環鏈表的表頭出發,正序對每個數據元素調用函數visit()
 DuLinkList p=L->next;//p指向首元結點
   while(p!=L)
   { visit(p->data);//對p所指結點調用函數visit()
   p=p->next;
   }
   printf("/n");
}

void ListTraverseBack(DuLinkList L,void(*visit)(ElemType))
{ //由雙向循環鏈表的表頭出發,逆序對每個元素調用函數visit()
 DuLinkList p=L->prior;//p指向尾結點
 while(p!=L)
 { visit(p->data);
   p=p->prior;
 }
   printf("/n");
}

void print(ElemType e)
{ printf("%2d",e);
}
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

主函數文件main2_6.cpp

#include<stdio.h>
#include"c2_4.h"

void main()
{ DuLinkList L;
  int i,k;
  ElemType e0,e,e1;
  InitList(L);
  for(i=1;i<=5;i++)
   ListInsert(L,i,i);
  printf("正序輸出:");
  ListTraverse(L,print);
  printf("逆序輸出:");
  ListTraverseBack(L,print);
  k=ListEmpty(L);
  printf("/n判斷表是否爲空:k=%d(1,是;0,否)",k);
  printf("/n判斷表的長度:%d/n",ListLength(L));
  printf("/n清空表/n");
  ClearList(L);
  printf("/n再次判斷表是否爲空/n");
  k=ListEmpty(L);
  printf("/n判斷表是否爲空:k=%d(1,是;0,否)",k);
  printf("/n判斷表的長度:%d/n",ListLength(L));

  printf("重新插入元素/n");
  for(i=1;i<=10;i++)
    ListInsert(L,i,i);
  ListTraverse(L,print);
  printf("/n前驅判斷/n");
  for(i=1;i<=10;i++)
  { GetElem(L,i,e);//將第i個元素的值賦給e
    k=PriorElem(L,e,e0);//判斷前驅
 if(k==ERROR)
  printf("元素%d沒有前驅/n",e);
 else
  printf("元素%d的前驅爲%d/n",e,e0);
  }

printf("/n後繼判斷/n");
for(i=1;i<=10;i++)
{ GetElem(L,i,e);
  k=NextElem(L,e,e1);
  if(k==ERROR)
   printf("元素%d沒有後繼/n",e);
  else
   printf("元素%d的前驅爲%d/n",e,e1);
}

printf("/n刪除元素/n");
for(i=1;i<=10;i++)
{   GetElem(L,i,e);
 ListDelete(L,e);

 
printf("刪除第%d個元素後,e值爲%d/n",i,e);
}
printf("/n清空表");
ClearList(L);
k=ListEmpty(L);
  printf("/n判斷表是否爲空:k=%d(1,是;0,否)",k);
  printf("/n判斷表的長度:%d/n",ListLength(L));


}

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/xinchow/archive/2010/04/08/5462222.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章