Chinaunix首页 | 论坛 | 博客
  • 博客访问: 145164
  • 博文数量: 52
  • 博客积分: 85
  • 博客等级: 民兵
  • 技术积分: 250
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-28 09:25
文章分类
文章存档

2013年(4)

2012年(48)

分类:

2012-03-06 11:38:32

原文地址:双向循环链表的实现 作者:zyhualove

 
 
 
《数据结构》中双向循环链表的实现
Status.h

/******************************************************************
      程序中要用到的 函数结果状态代码
******************************************************************/

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
// #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行

typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等

typedef int Boolean;

include.h

/******************************************************************
      程序中要用的头文件
******************************************************************/

 #include<string.h>
 #include<ctype.h>
 #include<malloc.h> // malloc()等

 #include<limits.h> // INT_MAX等

 #include<stdio.h> // EOF(=^Z或F6),NULL

 #include<stdlib.h> // atoi()

 #include<io.h> // eof()

 #include<math.h> // floor(),ceil(),abs()

 #include<process.h> // exit()

 #include<iostream.h> // cout,cin




/******************************************************************
      自定义头文件
******************************************************************/

#include "status.h"

dulist.h

#include "status.h"


typedef int ElemType;
//--------------双向链表的结构体-------------------------


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

//--------------双向链表的结构体-------------------------




/***********************************************************
* 函数声明 *
************************************************************/

Status InitList(DuLinkList *L);//产生空的双向循环链表L

Status DestroyList(DuLinkList *L);//销毁双向循环链表L

Status ListEmpty(DuLinkList L);//判断L是否为空,为空返回TRUE,否则返回FALSE

int ListLength(DuLinkList L);//返回L中元素的个数

Status ListInsert(DuLinkList *L, int i,ElemType e);//第i个位置之前插入元素e,i的合法值为1≤i≤表长+1

Status ListDelete(DuLinkList *L,int i,ElemType *e);//删除第i个元素并用e返回

Status ClearList(DuLinkList *L);//将L置为空表

Status GetElem(DuLinkList L,int i,ElemType *e);//获取第i个元素 并用e返回

int LocateElem(DuLinkList L,ElemType e,Status(*compare)(ElemType,ElemType));//返回第一个与e满足compare函数的元素的位序

Status PriorElem(DuLinkList L,ElemType cur_e , ElemType *pre_e);//获取前驱函数 用pre_e,返回cur_e的前驱 成功返回TRUE

Status NextElem(DuLinkList L,ElemType cur_e,ElemType *next_e);//获取后继函数,用next_e返回cur_e的后继元素

void ListTraverse(DuLinkList L,void(*visit)(ElemType));//正序对L中的每个元素调用visit函数

void ListTraverseBack(DuLinkList L,void(*visit)(ElemType));//逆序对L中的每个元素调用visit函数


dulist.c

/******************************************************************************
               在dulist.h中声明函数的实现
             线性表单链表的基本操作有14个
******************************************************************************/

#include "include.h"
#include "dulist.h"


//-----------------------初始化函数------------------------------------------

Status InitList(DuLinkList *L)
{//产生空的双向循环链表L

    (*L)=(DuLinkList)malloc(sizeof(DuLNode));
    if(*L)
    {
        (*L)->next=(*L)->prior=(*L);
        return OK;
    }
    else
        return OVERFLOW;
}
 
//-----------------------销毁函数--------------------------------------------

Status DestroyList(DuLinkList *L)
{//操作结果:销毁双向循环链表L

    DuLinkList q,p=(*L)->next;//p指向第一个结点

    while(p!=*L)
    {
        q=p->next;
        free(p);//释放p

        p=q;
    }
    free(*L);
    *L=NULL;
    return OK;
}

//------------------------判空函数--------------------------------------------

Status ListEmpty(DuLinkList L)
{//初始条件:线性表L存在。操作结果:若L为空表则返回TRUE否则返回FALSE

    if(L->next==L&&L->prior==L)
        return TRUE;
    else
        return FALSE;
}

//-------------------------计算L中元素个数------------------------------------

int ListLength(DuLinkList L)
{//初始条件:L存在。操作结果:返回L中数据元素的个数

    int i=0;
    DuLinkList p=L->next;//p指向第一个结点

    while(p!=L) //没到表头

    {
        i++;
        p=p->next;
    }
    return i;
}

//-------------------------返回第i个元素的位置指针-----------------------------

DuLinkList GetElemP(DuLinkList L,int i)
{//在双向链表L中返回第i个元素的位置指针

    int j;
    DuLinkList p=L;//p指向头结点

    for(j=1;j<=i;j++)
        p=p->next;
    return p;
}

//--------------------------插入函数-------------------------------------------

Status ListInsert(DuLinkList *L, int i,ElemType e)
{//在带头结点的双向循环链表中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1

    DuLinkList p,s;
    if(i<1||i>ListLength(*L)+1) //i值不合法

        return ERROR;
    p=GetElemP(*L,i-1);//将第i-1个元素的指针位置赋给p

    if(!p) //p=NULL,既第i-1个元素不存在

        return ERROR;
    s=(DuLinkList)malloc(sizeof(DuLNode));
    if(!s) //分配失败

        return OVERFLOW;
    s->data=e;
    s->prior=p;
    s->next=p->next;
    p->next->prior=s;
    p->next=s;
    return OK;
}

//-----------------------------删除函数---------------------------------------

Status ListDelete(DuLinkList *L,int i,ElemType *e)
{//删除带头结点的双想循环链表L第i个元素,i的合法值为1≤i≤表长,并用e返回

    DuLinkList p;
    if(i<1||i>ListLength(*L))//i值不合法

        return ERROR;
    p=GetElemP(*L,i);//在L中确定第i个元素的位置指针p

    if(!p) //p=NULL 即第i个元素不存在

        return ERROR;
    *e=p->data;
    p->prior->next=p->next;
    p->next->prior=p->prior;
    free(p);
    return OK;
}
//-----------------------------置空函数---------------------------------------

Status ClearList(DuLinkList *L)
{//初始条件:L存在 。操作结果:将L置空

    DuLinkList q,p=(*L)->next;//平指向第一个结点

    while(p!=*L) // 没到表头

    {
        q=p->next;
        free(p);
        p=q;
    }
    (*L)->next=(*L)->prior=*L;//头结点的指针域均指向自身

    return OK;
}

//---------------------- 获取元素函数-----------------------------------------

Status GetElem(DuLinkList L,int i,ElemType *e)
{//当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR

    int j=1;
    DuLinkList p=L->next;//p指向第一个结点

     while(p!=L&&j<i) //顺指针向后查找知道p指向第i个元素或p指向头结点

     {
         p=p->next;
         j++;
     }
     if(p==L||j>i) //第i个元素不存在

         return ERROR;
     *e=p->data; //取第i个元素

     return OK;
}

//----------------------------LocateElem函数--------------------------------------------

int LocateElem(DuLinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
{ // 初始条件:L已存在,compare()是数据元素判定函数 满足compare返回TRUE,否则返回FALSE

// 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。

    int i=0;
    DuLinkList p=L->next;//p指向第一个元素

    while(p!=L) //遍历L知道p指向头结点

    {
        i++;
        if(compare(p->data,e)) //找到和条件的元素

            return i;
        p=p->next;
    }
    return 0;
}


//---------------------------获取前驱函数----------------------------------------------

Status PriorElem(DuLinkList L,ElemType cur_e , ElemType *pre_e)
{// 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,

// 前驱,否则操作失败,pre_e无定义

     DuLinkList p=L->next->next; // p指向第2个元素

    while(p!=L) // p没到表头

    {
        if(p->data==cur_e)
        {
            *pre_e=p->prior->data;
            return TRUE;
        }
        p=p->next;
    }
    return FALSE;
}

//-------------------------获取后继函数------------------------------------------------

Status NextElem(DuLinkList L,ElemType cur_e,ElemType *next_e)
{ // 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,

   // 否则操作失败,next_e无定义

   DuLinkList p=L->next->next; // p指向第2个元素

   while(p!=L) // p没到表头

   {
     if(p->prior->data==cur_e)
     {
       *next_e=p->data;
       return TRUE;
     }
     p=p->next;
   }
   return FALSE;
}

//-----------------------------正序访问函数---------------------------------------------

void ListTraverse(DuLinkList L,void(*visit)(ElemType))
{ // 由双链循环线性表L的头结点出发,正序对每个数据元素调用函数visit()

   DuLinkList p=L->next; // p指向头结点

   while(p!=L)
   {
     visit(p->data);
     p=p->next;
   }
   printf("\n");
}

//------------------------------逆序访问函数--------------------------------------------

void ListTraverseBack(DuLinkList L,void(*visit)(ElemType))
{ // 由双链循环线性表L的头结点出发,逆序对每个数据元素调用函数visit()。另加

   DuLinkList p=L->prior; // p指向尾结点

   while(p!=L)
   {
     visit(p->data);
     p=p->prior;
   }
   printf("\n");
}
    


main.c

#include "include.h"
#include "dulist.h"


Status compare(ElemType c1,ElemType c2)
{// 判断两个数是否相等 相等返回TRUE,否则返回FALSE

    if(c1==c2)
        return TRUE;
    else
        return FALSE;
}

void visit(ElemType c)
{//把C输出

    printf("%d ",c);
}

 
void main()
{
    DuLinkList L,p;
    Status result; //返回状态 OK TRUE FALSE

    int i;
    ElemType e,pre_e,next_e;
    //--------------------------初始化函数测试-------------------------------

    //printf("初始化L前,L=%u\n",L);

    result=InitList(&L);
    if(result==OK)
        printf("初始化L成功,初始化后L=%u\n",L);
    //-----------------------------------------------------------------------

    //---------------------------判空函数测试--------------------------------

    result=ListEmpty(L);
    if(result==TRUE)
        printf("线性表L为空\n");
    else
        printf("线性表L不为空\n");
    //-----------------------------------------------------------------------

    //---------------------------计算元素个数测试----------------------------

    i=ListLength(L);
    printf("L中的元素个数为:%d\n",i);
    //-----------------------------------------------------------------------

    //---------------------------插入函数测试--------------------------------

    printf("依次插入 1 3 5 7\n");
    result=ListInsert(&L,1,1);
    result=ListInsert(&L,2,3);
    result=ListInsert(&L,3,5);
    result=ListInsert(&L,4,7);
    i=ListLength(L);
    printf("插入元素后L中的元素个数为:%d\n",i);
    printf("L中的元素值为:\n");
    p=L->next;
    while(p!=L)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
    //-----------------------------------------------------------------------

    //---------------------------删除L中元素函数测试-------------------------

    printf("删除L中的第3个元素并用e返回\n");
    result=ListDelete(&L,3,&e);
    //result=ListDelete(&L,6,&e);

    if(result==OK)
        printf("删除成功,删除的第3个元素值为:%d\n",e);
    else
        printf("删除失败,不存在此元素\n");
    printf("删除后L中的元素值为:\n");
    p=L->next;
    while(p!=L)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
    //-----------------------------------------------------------------------

    //---------------------------获取元素函数测试----------------------------

    printf("获取第3个元素的值并用e返回\n");
    result=GetElem(L,3,&e);
    if(result==OK)
        printf("第3个元素的值为:%d\n",e);
    //-----------------------------------------------------------------------

    //---------------------------判定函数测试--------------------------------

    printf("查看L中是否有与3相等的元素\n");
    i=LocateElem(L,3,compare);
    if(i)
        printf("第%d个元素的值与3相等\n",i);
    else
        printf("没有与3相等的元素\n");
    printf("查看L中是否有与6相等的元素\n");
    i=LocateElem(L,6,compare);
    if(i)
        printf("第%d个元素的值与3相等\n",i);
    else
        printf("没有与6相等的元素\n");
    //-----------------------------------------------------------------------

    //---------------------------获取前驱函数测试----------------------------

    result=PriorElem(L,3,&pre_e);
    if(result==TRUE)
        printf("在L中3的前驱为%d\n",pre_e);
    else
        printf("在L中3没有前驱元素\n");
    result=PriorElem(L,1,&pre_e);
    if(result==TRUE)
        printf("在L中1的前驱为%d\n",pre_e);
    else
        printf("在L中1没有前驱元素\n");
    //-----------------------------------------------------------------------

    //---------------------------获取后继函数测试----------------------------

    result=NextElem(L,3,&next_e);
    if(result==TRUE)
        printf("在L中3的后继为%d\n",next_e);
    else
        printf("在L中3没有后继元素\n");
    result=NextElem(L,7,&next_e);
    if(result==TRUE)
        printf("在L中7的后继为%d\n",next_e);
    else
        printf("在L中7没有后继元素\n");
    //-----------------------------------------------------------------------

    //---------------------------Traverse 函数测试---------------------------

    printf("正序输出L中的元素\n");
    ListTraverse(L,visit);
    printf("********************************\n");
    printf("逆序输出L中的元素\n");
    ListTraverseBack(L,visit);
    //-----------------------------------------------------------------------

    //---------------------------置空函数测试--------------------------------

    printf("将L置空\n");
    result=ClearList(&L);
    if(result==OK)
        printf("置空操作成功\n");
    printf("判断L是否为空\n");
    result=ListEmpty(L);
    if(result=TRUE)
        printf("置空后L为空的\n");
    //-----------------------------------------------------------------------

    //---------------------------销毁函数测试--------------------------------

    printf("销毁L...\n");
    result=0;
    result=DestroyList(&L);
    if(result==OK)
        printf("销毁L成功,销毁后L=%u\n",L);
    else
        printf("销毁失败\n");
    //-----------------------------------------------------------------------


}

阅读(533) | 评论(0) | 转发(0) |
0

上一篇:c的位操作

下一篇:STATIC详解

给主人留下些什么吧!~~