0x00数据结构——C语言实现(单向循环链表)

0x00数据结构——C语言实现(单向循环链表)

/*filename:circular_list.h*/
/*
 循环链表(circular list)是另一种形式的表示线性表的链表,与单链表不同的是,
 表尾结点的link域中不是NULL而是存放指向链表开始结点的指针。

 Functions:
    创建一个空线性表
    计算表长度
    返回附加头结点的地址
    搜索函数:找x在表中的位置,返回表项位置
    定位函数:返回第i个表项在表中的位置
    取第i个表项的值
    用x修改第i个表项的内容
    插入x在表中第i个表项之后,函数返回成功标志
    删除表中第i个表项,通过x返回删除表项的值,函数返回成功标志
    判断表空,空返回真,否则返回假
    判断表满:满返回真,否则返回假
    对当前的表排序

*/
#ifndef CIRCULAR_LIST
#define CIRCULAR_LIST

//假定每个表项的类型为T
typedef int T;
#define MAXLEN 100
typedef enum {
    false = 0,
    true
} BOOL;
//循环链表结点的数据结构
struct node;
typedef struct node cnode;
typedef struct node *to_node;
typedef to_node c_list;
typedef to_node pos;

//创建一个空循环链表
c_list create_list(void);

//将链表置为空表
BOOL set_empty(c_list l);

//计算表长度
int calc_length(c_list l);

//返回附加头结点的地址
pos head_addr(c_list l);

//搜索函数:找x在表中的位置,返回表项位置
pos search(c_list l, T x);

//定位函数:返回第i个表项在表中的位置
pos locate(c_list l, int i);

//取第i个表项的值
T get_val(c_list l, int i);

//用x修改第i个表项的内容
BOOL change_val(c_list l, int i, const T x);

//插入x在表中第i个表项之后,函数返回成功标志
BOOL insert_val(c_list l, int i, const T x);

//删除表中第i个表项,通过x返回删除表项的值,函数返回成功标志
BOOL delete_val(c_list l, int i, T *x);

//判断表空,空返回真,否则返回假
BOOL isempty(c_list l);

//输出
void output(c_list l);

//对当前的表排序
BOOL sort(c_list l);


#endif
/*filename:circular_list.c*/
#include <stdio.h>
#include <stdlib.h>
#include "circular_list.h"


/*
循环链表结点的数据结构
*/
struct node{
    T val;
    struct node *next;
};
/*
struct node;
typedef struct node cnode;
typedef struct node *to_node;
typedef to_node c_list;
typedef to_node pos;
*/
//该循环链表带头节点,头节点的val域存储链表的长度
/*
    -->{(头节点)|val|next|}->|val|next|->|val|next|->|val|next|->|val|next|--
    |                                                              |
    ---------------------------------------------------------------
*/

//创建一个空线性表
c_list create_list(void)
{
    c_list l = (c_list)malloc(sizeof(cnode));
    l->next = l;
    l->val = 0;
    return l;
}

//将链表置为空表
BOOL set_empty(c_list l)
{
    pos tmp = l->next, ttemp;
    while(tmp!=l){
        ttemp = tmp->next;
        free(tmp);
        tmp = ttemp;
    }
    l->next = l;
    l->val = 0;
    return true;
}

//计算表长度
int calc_val(c_list l)
{
    return l->val;
}

//返回附加头结点的地址
pos head_addr(c_list l)
{
    return l;
}

//搜索函数:找x在表中的位置,返回表项位置
pos search(c_list l, T x)
{
    int i = 1;
    pos tmp;
    tmp = l->next;
    while(tmp != l && tmp->val != x && i<=l->val){
        tmp = tmp->next;
        i++;
    }
    if(i>l->val) return NULL;
    else return tmp;
}

//定位函数:返回第i个表项在表中的位置
pos locate(c_list l, int i)
{
    if(i<=l->val && i>0){
        pos tmp;
        tmp = l;
        while(--i>=0){
            tmp = tmp->next;
            if(tmp == l)    break;
        }
        return tmp;
    } else {
        printf("can not access the %d'th element
", i);
        return NULL;
    }
}

//取第i个表项的值
T get_val(const c_list l, int i)
{
    if(i<=l->val && i>0){
        pos tmp;
        tmp = l;
        while(--i>=0){
            tmp = tmp->next;
            if(tmp == l)    break;
        }
        return tmp->val;
    } else {
        printf("can not access the %d'th element
", i);
        return -1;
    }
}

//用x修改第i个表项的内容
BOOL change_val(c_list l, int i, const T x)
{
    if(i<=l->val && i>0){
        pos tmp;
        tmp = l;
        while(--i>=0){
            tmp = tmp->next;
            if(tmp == l)    break;
        }
        tmp->val = x;
        return true;
    } else {
        return false;
    }
}

//插入x在表中第i个表项之后,函数返回成功标志
BOOL insert_val(c_list l, int i, const T x)
{
    if(i<=l->val && i>=0){
        pos tmp;
        tmp = l;
        while(--i>=0){
            tmp = tmp->next;
            if(tmp == l)    break;
        }
        to_node t = (to_node)malloc(sizeof(cnode));
        t->next = tmp->next;
        t->val = x;
        tmp->next = t;
        l->val++;
        return true;
    } else {
        return false;
    }
}

//删除表中第i个表项,通过x返回删除表项的值,函数返回成功标志
BOOL delete_val(c_list l, int i, T *x)
{
    if(i<=l->val && i>0){
        i--;
        pos tmp;
        tmp = l;
        while(--i>=0){
            tmp = tmp->next;
            if(tmp == l)    break;
        }
        *x = (tmp->next)->val;
        tmp->next = (tmp->next)->next;
        l->val--;
        return true;
    } else {
        return false;
    }
}

//判断表空,空返回真,否则返回假
BOOL isempty(const c_list l)
{
    return (l->val == 0 ? true:false);
}

//输出
void output(const c_list l)
{
    pos tmp = NULL;
    int i = 1;
    tmp = l->next;
    while(tmp!=l){
        printf("the %dth element is %d
", i++, tmp->val);
        tmp = tmp->next;
    }
}

//对当前的表排序
BOOL sort(const c_list l)
{
    if(l->val < 2) {
        return true;
    }
    //冒泡排序
    pos tmp, tmp1, tmp2;
    int i;
    tmp = l->next;
    while(tmp->next != l) {
        tmp1 = l->next;
        tmp2 = tmp1->next;
        while(tmp2 != l) {
            if(tmp1->val > tmp2->val) {
                i = tmp1->val;
                tmp1->val = tmp2->val;
                tmp2->val = i;
            }
            tmp1 = tmp1->next;
            tmp2 = tmp2->next;
        }
        tmp = tmp->next;
    }
    return true;
    //快速排序

    //归并排序

}
原文地址:https://www.cnblogs.com/born2run/p/9581345.html