码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构——单链表的实现

时间:2017-01-12 13:08:13      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:大于   insert   设置   线性表   表示   越界   数据类型   void   实现   

简单实现了单链表的功能,在查找、求前驱、插入、删除方法中判断了越界问题,并没有考虑其他可能产生的错误。

/*
    单链表:用一组地址任意的存储单元存放线性表中的数据元素
    结点(数据元素) = 元素(数据元素的映像) +    指针(指示后继元素的位置)
    以“结点的序列”表示线性表——单链表。
*/

#include<stdio.h>
#include<stdlib.h>

//定义数据类型
typedef int ElemType;

//单链表的存储结构
typedef struct LNode{
    ElemType data;    //数据域
    struct LNode *next;    //指针域
}LNode, *LinkList;

//声明,指针函数
void(*visit)(LNode *node);

//声明,辅助函数
void visitData(LNode *node);

//线性表带有头结点,因此第一个结点有前驱,即为头结点
//对单链表的基本操作
void CreateList(LinkList &L);    //创建线性表,从后往前建表
LinkList GetLNode(LinkList L, int i);    //返回第i个结点
LinkList GetFirst(LinkList L);    //返回第一个结点
LinkList PriorLNode(LinkList L, int i);    //返回第i结点的前驱结点
void ListTraverse(LinkList L, void(visit(LNode *node)));    //遍历单链表
void ListInsert(LinkList &L, int i, ElemType e);    //在第i个结点之前插入,数据域是e的结点
void AppendFirst(LinkList &L, ElemType e);    //在第一个结点之前插入,数据域是e的结点
void AppendLast(LinkList &L, ElemType e);    //在最后一个结点之后插入,数据域是e的结点
void ListDelete(LinkList &L, int i, LinkList &rNode);    //删除第i个结点并返回
void DeleteFirst(LinkList &L, LinkList &rNode);    //删除第一个结点并返回
void DeleteLast(LinkList &L, LinkList &rNode);    //删除最后一个结点并返回

//测试模块
int main(){
    LinkList L;
    printf("请创建单链表:");
    CreateList(L);
    ListTraverse(L, visitData);
    printf("\n");


    //获取第一个结点,最后一个结点(人为设置表长的),不存在的结点
    printf("第一个结点的值:%d\n", GetFirst(L)->data);
    printf("最后一个结点的值:%d\n", GetLNode(L, 6)->data);
    printf("索引小于1结点的值:%d\n", GetLNode(L, 0)->data);
    printf("索引大于表长结点的值:%d\n\n", GetLNode(L, 7)->data);

    //获取第一个结点,最后一个结点,不存在的结点的的前驱
    printf("第一个结点的前驱的值:%d\n", PriorLNode(L, 1)->data);
    printf("最后一个结点的前驱的值:%d\n", PriorLNode(L, 6)->data);
    printf("索引小于1结点:%s\n", PriorLNode(L,0));
    printf("索引大于表长结点:%s\n\n", PriorLNode(L, 7));

    //在第一个结点之前插入,在最后一个结点之前插入
    AppendFirst(L, 7);
    AppendLast(L, 0);
    ListTraverse(L, visitData);
    ListInsert(L, 3, 8);
    ListTraverse(L, visitData);
    printf("\n");

    LNode *rNode;
    //删除任意结点,删除第一个结点,删除最后一个结点
    ListDelete(L, 3, rNode);
    ListTraverse(L, visitData);
    DeleteFirst(L, rNode);
    DeleteLast(L, rNode);
    ListTraverse(L, visitData);

    system("pause");
    return 0;
}

//各函数定义模块
void visitData(LNode *node){
    printf("%4d", node->data);
}

void CreateList(LinkList &L){    //创建线性表,从后往前建表
    L = (LinkList)malloc(sizeof(LNode));
    if (!L)
        return;
    L->next = NULL;

    ElemType elem;

    scanf_s("%d", &elem);
    while (elem != -1){
        LNode *newNode = (LinkList)malloc(sizeof(LNode));
        if (!newNode)
            return;
        newNode->data = elem;
        newNode->next = L->next;
        L->next = newNode;
        scanf_s("%d", &elem);
    }
}

LinkList GetLNode(LinkList L, int i){    //返回第i个结点的值
    int j = 1;
    LNode *p = L->next;

    //找第i个结点
    while (p && j != i){
        p = p->next;
        j++;
    }

    if (j > i || !p){
        printf("\n不存在该结点!\n");
        return L;
    }

    return p;
}

LinkList GetFirst(LinkList L){    //返回第一个结点的值
    return GetLNode(L, 1);
}

LinkList PriorLNode(LinkList L, int i){    //返回第i结点的前驱结点
    int j = 1;
    LNode *p = L;

    //找第i-1个结点,而且第i个结点不为空
    while (p->next && j != i){
        p = p->next;
        j++;
    }

    if (j > i || !p->next){
        printf("\n在链表中不存在该结点,没有前驱!\n");
        return NULL;
    }

    return p;
}

void ListTraverse(LinkList L, void(visit(LNode *node))){    //遍历单链表
    LNode *p = L->next;
    while (p){
        visit(p);
        p = p->next;
    }
    printf("\n");
}

void ListInsert(LinkList &L, int i, ElemType e){    //在第i个结点之前插入,数据域是e的结点
    LNode *p = PriorLNode(L, i);
    LNode *newNode = (LinkList)malloc(sizeof(LNode));
    if (!newNode)
        return;
    newNode->data = e;

    newNode->next = p->next;
    p->next = newNode;
}

void AppendFirst(LinkList &L, ElemType e){    //在第一个结点之前插入,数据域是e的结点
    ListInsert(L, 1, e);
}

void AppendLast(LinkList &L, ElemType e){    //在最后一个结点之后插入,数据域是e的结点
    //找到最后一个结点
    LNode *p = L;
    while (p->next){
        p = p->next;
    }
    //新建一个结点
    LNode *newNode = (LinkList)malloc(sizeof(LNode));
    if (!newNode)
        return;
    newNode->data = e;
    //插入
    newNode->next = p->next;
    p->next = newNode;
}

void ListDelete(LinkList &L, int i, LinkList &rNode){    //删除第i个结点并返回
    LNode *p = PriorLNode(L, i);
    LNode *q = p->next;
    rNode = q;
    p->next = q->next;
    free(q);
}

void DeleteFirst(LinkList &L, LinkList &rNode){    //删除第一个结点并返回
    ListDelete(L, 1, rNode);
}

void DeleteLast(LinkList &L, LinkList &rNode){    //删除最后一个结点并返回
    //找到最后一个结点的前驱
    LNode *p = L;
    while (p->next->next){
        p = p->next;
    }
    LNode *q = p->next;
    rNode = q;
    free(q);
    p->next = NULL;
}

不积跬步,无以至千里;不积小流,无以成江海。坚持着。

数据结构——单链表的实现

标签:大于   insert   设置   线性表   表示   越界   数据类型   void   实现   

原文地址:http://www.cnblogs.com/yangxiaohe/p/6275777.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!