双向循环链表基本操作(C语言版)

View Code
#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 DbLNode
{ 
    ElemType data;
    DbLNode *prior,*next;
}DbLNode,*DbLinkList;

//函数声明
Status CreateList(DbLinkList &L);//初始化链表
Status ClearList(DbLinkList L);//清空表
Status DestroyList(DbLinkList &L);//销毁双向链表
Status IsEmpty(DbLinkList L);//判断表是否为空
int GetLength(DbLinkList L);//判断表的长度
Status GetElemValue(DbLinkList L,int i,ElemType &e);//返回第i个元素的值
int LocateElem(DbLinkList L,ElemType e,Status(*compare)(ElemType,ElemType));//返回L中第1个与e满足关系compare()的数据元素的位序
Status GetPrevElemValue(DbLinkList L,ElemType cur_e,ElemType &pre_e);//前驱判断
Status GetNextElemValue(DbLinkList L,ElemType cur_e,ElemType &next_e);//后继判断
DbLinkList GetElem(DbLinkList L,int i);//返回第i个元素的地址
Status Insert(DbLinkList L,int i,ElemType e);//在表的第i个位置之前插入元素e
Status DeleteNode(DbLinkList L,int nPos);//删除表中第i个元素
void TraverseForward(DbLinkList L,void(*visit)(ElemType));//正序对每个元素调用函数visit()
void TraverseBack(DbLinkList L,void(*visit)(ElemType));//逆序对每个元素调用函数visit()
void print(ElemType e);
Status SortList(DbLinkList L);
Status ReverseList(DbLinkList L);
View Code
#include <stdio.h>
#include "dblinklist.h"
#include "gtest.h"


//产生空的双向循环链表
Status CreateList(DbLinkList &L)
{
    L = (DbLinkList)malloc(sizeof(DbLNode));
    if(L)
    {
        L->next = L->prior=L;
        L->data = 0;
    }
    else
    {
        return ERROR;
    }
    return OK;
}

//清空链表(清空有效节点)头结点仍然存在
Status ClearList(DbLinkList L)
{ 
    DbLNode* pCur = L->next;
    while(pCur != L)
    {  
        pCur = pCur->next;
        free(pCur->prior);
        pCur->prior = NULL;
    }
    L->next = L->prior = L;
    return OK;
}

//连头结点也不留,全部咔嚓
Status DestroyList(DbLinkList &L)
{ 
    ClearList(L);
    free(L);
    L=NULL;
    return OK;
}

//判断表是否为空
Status IsEmpty(DbLinkList L)
{ 
    return (L->next == L && L->prior == L);
}

//返回表的长度
int GetLength(DbLinkList L)
{ 
    int nLen = 0;
    DbLNode* p = L->next;
    while(p != L)
    { 
        nLen++;
        p = p->next;
    }
    return nLen;
}

//获取第nPos个元素,将值赋给e
Status GetElemValue(DbLinkList L,int nPos,ElemType &elem)
{ 
    int nCur = 1;
    DbLNode* pCur = L->next;//p指向第一个结点
    while(pCur != L && nCur < nPos)//顺指针向后查找,直到p指向第nPos个元素
    { 
        nCur++;
        pCur = pCur->next;
    }
    if(pCur == L || nCur > nPos)
    {
        return ERROR;
    }
    elem = pCur->data;
    return OK;
}

//返回表中第1个与e满足关系compare()的数据元素的位置
int LocateElem(DbLinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
{ 
    int nPos = 0;
    DbLNode* pCur = L->next;
    while(pCur != L)//p未指向头结点
    { 
        nPos++;//计数器加1
        if(compare(pCur->data,e))
        {
            //找到这样的元素
            return nPos;
        }
        pCur = pCur->next;
    }
    return -1;
}

Status GetPrevElemValue(DbLinkList L,ElemType curElem,ElemType &prevElem)
{ 
    DbLNode* pCur = L->next->next;//p指向第2个元素
    while(pCur != L)
    { 
        if(pCur->data == curElem)//p指向值为cur_e的结点
        {
            prevElem = pCur->prior->data;//将p的前驱结点的值赋给
            return OK;
        }
        pCur = pCur->next;
    }
    return ERROR;
}

Status GetNextElemValue(DbLinkList L,ElemType curElem,ElemType &nextElem)
{
    DbLNode* pCur = L->next->next;//p指向第二个元素
    while(pCur != L)
    { 
        if(pCur->prior->data == curElem)//p所指结点的前驱指向cur_e
        { 
            nextElem = pCur->data;//将p所指结点的值赋给next_e
            return OK;
        }    
        pCur = pCur->next;
    }
    return ERROR;
}

//在双向链表中返回第i个元素的节点指针
DbLNode* GetElem(DbLinkList L,int nPos)
{
    //异常判断
    if(nPos < 0||nPos > GetLength(L))
    {
        return NULL;
    }
    int nIndex = 1;
    DbLNode* p = L;//p指向头结点
    for(nIndex = 1; nIndex <= nPos; nIndex++)//p指向第i个结点
    {
        p = p->next;//p指向下一个结点
    }
    return p;
}

//在链表第i个位置上插入元素
Status Insert(DbLinkList L,int nPos,ElemType elem)
{ 
    DbLNode *pCur = NULL;
    DbLNode *pNew = NULL;

    if(nPos < 1 || nPos > GetLength(L) + 1)
    {
        return ERROR;
    }
    pCur = GetElem(L,nPos-1);//在L中确定第i个结点前驱的位置指针p
    if(!pCur) 
    {
        return ERROR;
    }
    pNew = (DbLNode*)malloc(sizeof(DbLNode));//生成新结点
    if(!pNew) 
    {
        return ERROR;
    }
    pNew->data = elem;//将e赋给新的结点
    pNew->prior = pCur;//新结点的前驱为第i-1个结点
    pNew->next = pCur->next;//新结点的后继为第i个结点
    pCur->next->prior = pNew;//第i个结点的前驱指向新结点
    pCur->next = pNew;//第i-1个结点的后继指向新结点
    return OK;
}

//删除第i个结点
Status DeleteNode(DbLinkList L,int nPos)
{  
    if(nPos < 1)
    {
        return ERROR;
    }
    DbLNode* pDel = NULL;
    pDel = GetElem(L,nPos);//在L中确定第i个元素的位置指针
    if(!pDel) 
    {
        return ERROR;
    }
    pDel->prior->next = pDel->next;//第原i-1个结点的后继指向原第i+1个结点
    pDel->next->prior = pDel->prior;//第原i+1个结点的前驱指向原第i-1个结点
    free(pDel);
    pDel = NULL;
    return OK;
}

//由双向循环链表的表头出发,正序对每个数据元素调用函数visit()
void TraverseForward(DbLinkList L,void(*visit)(ElemType))
{
    DbLNode* pCur = L->next;//p指向首元结点
    while(pCur != L)
    { 
        visit(pCur->data);//对p所指结点调用函数visit()
        pCur = pCur->next;
    }
    printf("\n");
}

//由双向循环链表的表头出发,逆序对每个元素调用函数visit()
void TraverseBack(DbLinkList L,void(*visit)(ElemType))
{ 
    DbLinkList pCur = L->prior;//p指向尾结点
    while(pCur != L)
    { 
        visit(pCur->data);
        pCur = pCur->prior;
    }
    printf("\n");
}

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

//链表排序,冒泡
Status SortList(DbLinkList L)
{
    if (IsEmpty(L))
    {
        return ERROR;
    }
    DbLNode *p = L->next;
    DbLNode *q = NULL;
    for (; p != L; p = p->next)
    {
        for (q = p->next; q != L; q = q->next)
        {
            if (p->data > q->data)
            {
                int nTemp = p->data;
                p->data = q->data;
                q->data = nTemp;
            }
        }
    }
    return OK;
}

//链表逆序
Status ReverseList(DbLinkList L)
{
    if (IsEmpty(L))
    {
        return ERROR;
    }
    DbLNode *pCur = L->next;
    L->prior = L->next = L;
    DbLNode *pNew = NULL;
    while (pCur != L)
    {
        pNew = pCur;
        pCur = pCur->next;
        pNew->prior = L;
        pNew->next = L->next;
        L->next->prior = pNew;
        L->next = pNew;
    }
    L->prior = pCur->prior;
    return OK;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int main(int argc, char* argv[])
{
    /*testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();*/
    DbLinkList L = NULL;
    CreateList(L);
    for (int i = 0; i < 5; ++i)
    {
        Insert(L,1,i);
    }
    if (!Insert(L,10,10))
    {
        printf("Insert Failed\n");
    }
    
    printf("Before Sort:\n");
    TraverseForward(L,print);
    SortList(L);
    printf("After Sort:\n");
    TraverseForward(L,print);
    printf("After Reverse:\n");
    ReverseList(L);
    TraverseForward(L,print);
    printf("插入元素测试\n");
    int nPos = 0;
    int nElem = 0;
    while (nPos != -1)
    {
        scanf("%d",&nPos);
        scanf("%d",&nElem);
        printf("插入元素: pos = %d,Elem = %d\n",nPos,nElem);
        if (Insert(L,nPos,nElem))
        {
            TraverseForward(L,print);            
        }
        else
        {
            printf("Insert Failed\n");
        }
    }
    printf("插入元素测试完毕\n");


    return 0;
}

 

posted on 2012-06-17 15:42  AlanLau2011  阅读(401)  评论(0编辑  收藏  举报

导航