带头结点的线性链表的编写与实现

4月1号,完成头文件的编写
明天写实现。
4月2号,补充插入元素。

/*线性表的链式存储结构的特点是用一组任意的
**存储单元存储线性表的数据元素
**(这组存储数据元素可以是连续的,也可以是不连续的)
*/

#include <stdlib.h>
#define TRUE    1
#define FALSE   0
#define OK      1
#define ERROR   0
#define OVERFLOW    -1
#define INFEASIBLE  -2

typedef int Status;
typedef int ElemType;

//结点类型
typedef struct LNode{
    ElemType data;      //结点所存储的数据
    struct LNode *next; //指向下一个结点的指针
}*Link, *Position;


//链表类型
typedef struct{
    Link head;      //指向链表的头结点
    Link tail;      //指向链表的尾结点
    int length;         //链表的数据元素的个数
}LinkList;


//分配由 p 指向的值为 e 的结点,并返回 OK;若分配失败,则返回 ERROR
Status MakeNode( Link &p, ElemType e ){
    p = (Link) malloc (sizeof(LNode));
    if( !p )
        return ERROR;
    p -> data = e;
    p -> next = NULL;
    return OK;
}

//释放 p 所指结点
void FreeNode( Link p ){
    p -> data = NULL;
    p -> next = NULL;
    free(p);
}

//构造一个空链表
Status InitList( LinkList &L ){
    Link p;
    p = (Link) malloc (sizeof(LNode));
    if( p ){
        p -> next = NULL;
        L.head = L.tail = p;
        L.length = 0;
        return OK;
    }
    else
        return ERROR;
}

//将线性表 L 重置为空表,并释放链表的结点空间
Status ClearList( LinkList &L ){
    Link p, q;
    if( L.head != L.tail ){
        p = L.head -> next;
        L.head -> next = NULL;
        while( p != L.tail ){
            q = p -> next;
            free(p);
            p = q;
        }
        free(q);
        L.head = L.tail;
        L.length = 0;
        return OK;
    }
    else
        return ERROR;
}

//销毁线性链表 L, L 不再存在
Status DestroyList( LinkList &L ){
    ClearList(L);
    free(L.head);
    L.tail = NULL;
    return OK;
}

//已知 h 指向线性链表的头结点,将 s 所指结点插入在第一个结点之前
Status InsFirst( LinkList &L,Link h, Link s ){
    s -> next = h -> next;
    h -> next = s;
    if( h == L.tail )
        L.tail = h -> next;
    L.length++;
    return 0;
}

//已知 h 指向线性链表的头结点,删除链表中的第一个结点并以 q 返回
Status DelFirst( LinkList L, Link h, Link &q ){
    q = h -> next;
    h -> next = q -> next;
    if( h == L.tail )
        L.tail = h -> next;
    L.length--;
    return ( q -> data );
}

//将指针 s 所指(彼此以指针相链)的一串结点链接在线性链表 L 的最后一个结点
//之后,并改变链表 L 的尾指针指向新的尾结点
Status Append( LinkList &L, Link s){
    int i;
    while( s -> next ){
        s = L.tail -> next;
        s = s -> next;
        i++;
    }
    L.tail -> next = s;
    L.length += i;
    return OK;
}

//删除线性链表 L 中 的尾结点并以 q 返回,改变链表 L 的尾指针指向新的尾结点
Status Remove( LinkList &L, Link &q ){
    Link m;
    if( L.head != L.tail ){
        m = L.head;
        while( m -> next != L.tail )
            m = m -> next;
        q = L.tail;
        m -> next = NULL;
        L.tail = m;
        L.length--;
        return OK;
    }
    else{ 
        q = NULL;
        return FALSE;
    }
}

//已知 p 指向线性链表 L 中的一个结点,将 s 所指结点插入在 p 所指结点之前
//并修改指针 p 指向新的插入点
Status InsBefore( LinkList &L, Link &p, Link s ){
    Link m;
    m = L.head;
    if( L.head != L.tail ){
        while( m -> next != p )
            m = m -> next;
        s = m -> next;
        s -> next = p;
        p -> next = s;
        L.length++;
        return OK;
    }
    else
        return ERROR;
}

//已知 p 指向线性链表 L 中的一个结点,将 s 所指结点插入在 p 所指结点之后
//并修改指针 p 指向新插入的结点
Status InsAfter( LinkList &L, Link &p, Link s ){
    Link m;
    m = L.head;
    if( L.head != L.tail ){
        while( m != p )
            m = m -> next;
        m -> next = s;
        s -> next = m -> next;
        L.length++;
        return OK;
    }
    else
        return FALSE;
}

//已知 p 指向线性链表 L 中的一个结点,用 e 更新 p 所指结点中数据元素的值
Status SetCurElem( LinkList L, Link &p, ElemType e ){
    Link q;
    q = L.head -> next;
    while( q != p )
        q = q -> next;
    q -> data = e;
    return OK;
}

//已知 p 指向线性链表中的一个结点,返回 p 所指结点中数据元素的值
ElemType GetCurElem( LinkList L, Link p ){
    Link q;
    q = L.head -> next;
    while( q != p )
        q = q -> next;
    return ( q -> data );
}

//若线性链表 L 为空表,则返回 TRUE, 否则返回 FALSE
Status ListEmpty( LinkList L ){
    if( L.head = L.tail)
        return TRUE;
    else
        return FALSE;
}

//返回线性链表 L 中元素个数
int ListLength( LinkList L ){
    return L.length;
}

//返回线性链表 L 中头结点的位置
Position GetHead( LinkList L ){
    return L.head;
}

//返回线性链表 L 中最后一个结点的位置
Position GetLast( LinkList L ){
    return L.tail;
}

//已知 p 指向线性链表 L 中的一个结点,返回 p 所指结点的直接前驱的位置
//若无前驱,则返回 NULL
Position PriorPos( LinkList L, Link p ){
    Link m;
    m = L.head;
    if( L.head -> next != p ){
        while( m ->next != p )
            m = m -> next;
        return m;
    }
    else
        return NULL;
}

//已知 p 指向线性链表 L 中的一个结点,返回 p 所指结点的直接后继的位置
//若无后继,则返回NULL
Position NextPos( LinkList L, Link p ){
    Link m;
    m = L.head;
    if( L.tail -> next != p ){
        while( m != p )
            m = m -> next;
        m = m -> next;
        return m;
    }
    else
        return NULL;
}

//返回 p 指示线性链表 L 中的第 i 个结点的位置并返回OK, i 值不合法时返回ERROR, i = 0 为头结点
Status LocatePos( LinkList L, int i, Link &p ){
    int j;
    if( i < 0 || i > ListLength(L) )
        return ERROR;
    else{
        p = L.head;
        for( j = 1; j <= i; j++ ){
            p = p -> next;
        }
        return OK;
    }
}

//返回线性链表 L 中第一个与 e 满足函数 compare() 判定关系的元素的位置
//若不存在这样的元素,则返回NULL
Position LocateElem( LinkList L, ElemType e,
                    Status (*compare)(ElemType e1, ElemType e2)){
    Link m;
    m = L.head;
    int i;
    while( !compare( m -> data, e) ){
        m = m -> next;
        i++;
    }
    if( i > ListLength(L) )
        return NULL;
    return m;
}

//在第 i 个元素之前插入元素
Status ListInsert( LinkList &L, int i, ElemType e ){
    Link h;
    Link s;
    if( !LocatePos(L,i-1, h) )
        return ERROR;
    if( !MakeNode( s, e ) )
        return ERROR;
    InsFirst( L, h, s );        //对于从第 i 个结点开始的链表,第 i - 1 个结点是它的头结点
    return OK;
}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值