数据结构-单向循环链表(初始化、插入结点、删除结点等操作)

单向循环链表


单向循环链表:将单向链表的最后一个结点指向头结点形成一个环,即成为单向循环链表,可以通过其中任意一个结点出发访问到其他结点。单向循环链表的操作方法与单向链表相似,只是在于循环条件存在差异。
特点

  • 若链表为空,则头结点的next结点还是指向其本身,即head ->next=head;
  • 尾节点的next指针指向head结点,即头尾相连;
  • 通过判断当前结点的next结点是否与head结点相等,即可判断是否对单向循环链表遍历完成;
  • 循环链表无须增加存储量,仅对单向链表的链接方式稍作改变,即可使得单向链表处理更加方便灵活。

单向循环链表结构如下图所示:
单向循环链表
:单向循环链表不一定存在头结点

单向循环链表宏定义及数据类型

//定义处理的数据类型
typedef int ElemType;
#define bool int

//定义状态
typedef enum Status
{
    success, fail, fatal, rang_err
}Status;

//定义数据类型的结构
typedef struct Node
{
    ElemType data;
    struct Node *next;
}Node,*PtrList;

单向循环链表初始化

/************************************************************
 * 函数名称:InitList(PtrList list,int size)
 * 功能描述:初始化循环链表
 * 传入参数:PtrList lis       待初始化的循环链表
 *           int size          初始化的循环链表长度
 * 返回值:fail    失败
 *         success 成功
 ************************************************************/
Status InitList(PtrList list, int size)
{
    Status _outcome_ = fail;
    int i = 1;
    ElemType elem;
    list = (PtrList)malloc(sizeof(Node));
    PtrList Tail;
    PtrList Temp;
    if(list != NULL)
    {
        list -> data = 0;
        list -> next = list;/*第一个节点不保存数据*/
        Tail = list;
        for(; i< size+1;size++)
        {
            Temp = (PtrList)malloc(sizeof(Node));
            if(Temp == NULL)
            {
                return _outcome_;
            }
            printf("请输入第%d个节点的数据:",i)
            scanf("%d",&elem);

            Temp -> data = elem;
            Temp ->next = list;

            Tail ->next = Temp;
            Tail = Temp;
            _outcome_ = success;
        }
    }
    return _outcome_;
}

单向循环链表插入数据

/************************************************************
 * 函数名称:InitList(PtrList list,int size)
 * 功能描述:循环链表插入数据
 * 传入参数:PtrList lis       传入的循环链表
 *           int i             插入的位置
 *           ElemType elem     插入的数据
 * 返回值:fail    失败
 *         success 成功
 ************************************************************/
Status InsertList(PtrList list, int i,ElemType elem)
{
    Status _outcome_ = fail;
    PtrList Temp = NULL,Target = NULL;
    if(i == 1)/*循环链表头部插入结点*/
    {
        Temp = (PtrList)malloc(sizeof(Node));
        if(NULL == Temp)
        {
            return _outcome_;
        }
        Temp -> data = elem;
        for( Target = list; Target != list; Target = Target -> next);/*找到最后一个结点*/
        Temp -> next = list;
        Target ->next = Temp;
        list = Temp;/*新插入的结点作为头节点*/
        _outcome_ = success;
    }
    else
    {
        Target = list;
        for(int j = 1; j < (i-1); j++)
        {
            Target = Target -> next;/*找到第i-1个节点*/
        }
        Temp = (PtrList)malloc(sizeof(Node));
        if(Temp == NULL)
        {
            return _outcome_;
        }
        Temp ->next = Target ->next;
        Temp ->data = elem;
        Target -> next = Temp;
        _outcome_ = success;
    }
    return _outcome_;
}

单向循环链表删除结点

/************************************************************
 * 函数名称:DeleteList(PtrList list, int i)
 * 功能描述:循环链表删除数据
 * 传入参数:PtrList lis       传入的循环链表
 *           int i             删除的位置
 * 返回值:fail    失败
 *         success 成功
 ************************************************************/
Status DeleteList(PtrList list, int i)
{
    Status _outcome_ = fail;
    PtrList Target = NULL,Temp = NULL;
    if(i == 1)
    {
        for(Target = list;Target ->next != list;Target = Target -> next);/*找到尾结点*/
        Target ->next = list ->next;
        Temp = list;
        list = list ->next;
        free(Temp);
        if( NULL != Temp)
        {
            return _outcome_;
        }
        _outcome_ = success;
    }
    else
    {
        Target = list;
        for(int j = 1; j < i-1; j++)
        {
            Target = Target -> next;/*找到第i-1个结点*/
        }
        Temp = Target ->next;
        Target ->next = Temp ->next;
        free(Temp);
        if(NULL != Temp)
        {
            return _outcome_;
        }
        _outcome_ = success;
    }
    return _outcome_;
}

返回单向循环链表中结点位置

/************************************************************
 * 函数名称:SearchList(PtrList list, ElemType elem)
 * 功能描述:返回节点所在位置
 * 传入参数:PtrList lis       传入的循环链表
 *           ElemType  elem    结点数据        
 * 返回值:结点位置
 *         若返回0表示循环链表中不存在该结点
 ************************************************************/
int SearchList(PtrList list, ElemType elem)
{
    PtrList Target = list;
    PtrList listHead = list;
    int num = 0;
    
    while((Target -> data != elem) && (Target -> next != listHead))
    {
        ++num;
        Target = Target -> next;
    }
    
    if(Target -> next == listHead && Target -> data != elem)
    {
        return fail;
    }
    
    return num;
}
顺序表的初始化: ```c #define MAXSIZE 100 // 假设顺序表的最大长度为100 typedef struct { int data[MAXSIZE]; // 用数组存储数据元素 int length; // 顺序表的当前长度 } SqList; void InitList(SqList *L) { for(int i = 0; i < MAXSIZE; i++) { L->data[i] = 0; // 将所有元素初始化为0 } L->length = 0; // 初始化长度为0 } ``` 顺序表的插入操作: ```c bool InsertList(SqList *L, int i, int e) { if(i < 1 || i > L->length + 1) { // 判断插入位置是否合法 return false; } if(L->length >= MAXSIZE) { // 判断顺序表是否已满 return false; } for(int j = L->length; j >= i; j--) { // 将第i个元素及之后的元素后移 L->data[j] = L->data[j-1]; } L->data[i-1] = e; // 插入新元素 L->length++; // 长度加1 return true; } ``` 顺序表的删除操作: ```c bool DeleteList(SqList *L, int i) { if(i < 1 || i > L->length) { // 判断删除位置是否合法 return false; } for(int j = i; j < L->length; j++) { // 将第i个元素之后的元素前移 L->data[j-1] = L->data[j]; } L->length--; // 长度减1 return true; } ``` 单向链表初始化: ```c typedef struct Node { int data; struct Node *next; } Node, *LinkList; void InitList(LinkList *L) { *L = (LinkList) malloc(sizeof(Node)); // 分配头结点空间 (*L)->next = NULL; // 头结点指针域置为空 } ``` 单向链表插入操作: ```c bool InsertList(LinkList *L, int i, int e) { if(i < 1) { // 判断插入位置是否合法 return false; } Node *p = *L; int j = 0; while(p && j < i-1) { // 查找第i-1个结点 p = p->next; j++; } if(!p || j > i-1) { // 插入位置不合法 return false; } Node *s = (Node*) malloc(sizeof(Node)); // 分配新结点空间 s->data = e; // 插入结点 s->next = p->next; p->next = s; return true; } ``` 单向链表删除操作: ```c bool DeleteList(LinkList *L, int i) { if(i < 1) { // 判断删除位置是否合法 return false; } Node *p = *L; int j = 0; while(p->next && j < i-1) { // 查找第i-1个结点 p = p->next; j++; } if(!(p->next) || j > i-1) { // 删除位置不合法 return false; } Node *q = p->next; // 删除结点 p->next = q->next; free(q); return true; } ``` 双向链表初始化: ```c typedef struct DNode { int data; struct DNode *prior, *next; } DNode, *DLinkList; void InitList(DLinkList *L) { *L = (DLinkList) malloc(sizeof(DNode)); // 分配头结点空间 (*L)->prior = NULL; // 头结点的前驱指针置为空 (*L)->next = NULL; // 头结点的后继指针置为空 } ``` 双向链表插入操作: ```c bool InsertList(DLinkList *L, int i, int e) { if(i < 1) { // 判断插入位置是否合法 return false; } DNode *p = *L; int j = 0; while(p && j < i-1) { // 查找第i-1个结点 p = p->next; j++; } if(!p || j > i-1) { // 插入位置不合法 return false; } DNode *s = (DNode*) malloc(sizeof(DNode)); // 分配新结点空间 s->data = e; // 插入结点 s->prior = p; s->next = p->next; if(p->next) { // 如果p不是最后一个结点 p->next->prior = s; } p->next = s; return true; } ``` 双向链表删除操作: ```c bool DeleteList(DLinkList *L, int i) { if(i < 1) { // 判断删除位置是否合法 return false; } DNode *p = *L; int j = 0; while(p->next && j < i-1) { // 查找第i-1个结点 p = p->next; j++; } if(!(p->next) || j > i-1) { // 删除位置不合法 return false; } DNode *q = p->next; // 删除结点 if(q->next) { // 如果q不是最后一个结点 q->next->prior = p; } p->next = q->next; free(q); return true; } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值