数据结构-线性表_单链表

链表是一种复杂的数据结构,其数据之间的相互关系使链表分成三种:单链表、循环链表、双向链表,这篇文章介绍单链表的实现。

单链表有一个头节点head,指向链表在内存的首地址。链表中的每一个节点的数据类型为结构体类型,节点有两个成员:数据成员(实际需要保存的数据)和指向下一个结构体类型节点的指针即下一个节点的地址(事实上,此单链表是用于存放整型数据的动态数组)。链表按此结构对各节点的访问需从链表的头找起,后续节点的地址由当前节点给出。无论在表中访问那一个节点,都需要从链表的头开始,顺序向后查找。链表的尾节点由于无后续节点,其指针域为空,写作为NULL。

  • C/C++代码:

功能定义

/*
 * SLNode.h
 *
 *  Created on: 2016年6月8日
 *      Author: ThinkPad
 */

#ifndef SLNODE_H_
#define SLNODE_H_

#define FALSE 0
#define TRUE 1
typedef char SLNodeDataType;    //假设结点的数据域类型为字符
typedef struct Node {       //结点类型定义
    SLNodeDataType data;    //结点的数据域
    struct Node *next;      //结点的指针域
} SLNode;

/*
 * 初始化单链表
 */
void InitSLNode(SLNode **head);

/*
 * 获取链表长度
 */
int SLNodeLength(SLNode *head);

/*
 * 判断链表是否为空
 */
int SLNodeIsEmpty(SLNode *head);

/*
 * 在末尾添加
 */
int SLNodeAdd(SLNode *head, SLNodeDataType data);

/*
 * 插入数据
 */
int SLNodeInsert(SLNode *head, int index, SLNodeDataType data);

/*
 * 获取指定位置的数据
 */
int SLNodeGet(SLNode *head, int index, SLNodeDataType *data);

/*
 * 修改指定位置的数据
 */
int SLNodeUpdate(SLNode *head, int index, SLNodeDataType data);

/*
 * 删除指定位置的数据
 */
int SLNodeRemove(SLNode *head, int index, SLNodeDataType *data);

/*
 * 查找并返回数据位置(1~length)
 */
int SLNodeSearch(SLNode *head, SLNodeDataType data);

/*
 * 销毁链表
 */
void SLNodeDestroy(SLNode **head);
/*
 * 打印链表内容
 */
void ShowSLNode(SLNode *head);

#endif /* SLNODE_H_ */

功能实现

/*
 * SLNode.c
 *
 *  Created on: 2016年6月8日
 *      Author: 龙叔
 */
#include <stdio.h>
#include <stdlib.h>
#include "SLNode.h"

void InitSLNode(SLNode **head) {
    if ((*head = (SLNode*) malloc(sizeof(SLNode))) == NULL)
        exit(0);
    (*head)->next = NULL;
}

int SLNodeLength(SLNode *head) {
    if (head == NULL)   //链表空
        return 0;
    int length = 0;     //计数器初始为0
    SLNode *p = head;   //p指向头结点
    while (p->next != NULL) {
        p = p->next;
        length++;
    }
    return length;
}

int SLNodeIsEmpty(SLNode *head) {
    if (NULL == head)
        return TRUE;
    else
        return FALSE;
}

int SLNodeAdd(SLNode *head, SLNodeDataType data) {
    if (NULL == head)
        return FALSE;
    SLNode *p = head, *node;
    while (p->next != NULL) {   //寻找第i个结点//
        p = p->next;
    }
    if ((node = (SLNode*) malloc(sizeof(SLNode))) == NULL)
        exit(0);
    node->data = data;  //先存入数据
    node->next = NULL;  //尾部为空
    p->next = node;     //添加到末尾
    return TRUE;
}

int SLNodeInsert(SLNode *head, int index, SLNodeDataType data) {
    if (head == NULL) //链表不存在
        return FALSE;

    int pos = 0;    //记录当前位置
    SLNode *p = head, *node;

    //排除错误位置
    if (index < 0 || index > SLNodeLength(head)) {
        printf("SLNodeInsert: index插入位置错误!\n");
        return FALSE;
    }

    while (p->next != NULL && pos < index) {    //寻找第index个结点
        p = p->next;
        pos++;
    }
    if (pos != index) {
        printf("插入位置错误!\n");
        return FALSE;
    }
    if ((node = (SLNode*) malloc(sizeof(SLNode))) == NULL)
        exit(0);
    node->data = data;  //先存入数据
    node->next = p->next;
    p->next = node;     //最后完成
    return TRUE;
}

int SLNodeGet(SLNode *head, int index, SLNodeDataType *data) {
    int length = SLNodeLength(head);
    if (index < 0 || index > length) {
        printf("SLNodeGet: index位置错误\n");
        return FALSE;
    }
    SLNode *p = head;
    for (int i = 0; i < length; ++i) {
        p = p->next;
        if (i == index) {
            *data = p->data;
        }
    }
    return TRUE;
}

int SLNodeUpdate(SLNode *head, int index, SLNodeDataType data) {
    int length = SLNodeLength(head);
    if (index < 0 || index > length) {
        printf("SLNodeUpdate: index位置错误\n");
        return FALSE;
    }
    int pos = 0;
    SLNode *p = head;
    while (p->next != NULL && index != pos) {
        p = p->next;
        pos++;
    }
    p->next->data = data;
    return TRUE;
}

int SLNodeRemove(SLNode *head, int index, SLNodeDataType *data) {
    int length = SLNodeLength(head);
    if (index < 0 || index > length) {
        printf("SLNodeUpdate: index位置错误\n");
        return FALSE;
    }
    int pos = 0;
    SLNode *p = head, *remove;
    while (p->next != NULL && index != pos) {
        p = p->next;
        pos++;
    }
    remove = p->next;
    if (NULL != data) {
        *data = remove->data;       //记录删除的数据
    }
    p->next = p->next->next;    //删除
    free(remove);
    return TRUE;
}

int SLNodeSearch(SLNode *head, SLNodeDataType data) {
    if (NULL == head)
        return FALSE;
    int index = 0;
    SLNode *p = head;
    for (; index < SLNodeLength(head); ++index) {
        p = p->next;
        if (p->data == data)
            return index + 1;
    }

    return FALSE;
}

void SLNodeDestroy(SLNode **head) {
    if (NULL == (*head)) {
        return;
    }
    SLNode *point = *head, *dest;
    while (point != NULL) {
        dest = point;
        point = point->next;
        free(dest);
        dest = NULL;
    }
    *head = NULL;
}

void ShowSLNode(SLNode *head) {
    printf("ShowSLNode:\n");
    int length = SLNodeLength(head);
    SLNode *p = head;
    for (int i = 0; i < length; ++i) {
        p = p->next;
        printf(" %c\t", p->data);
    }
    printf("\n");
}

功能测试

/*
 * main.c
 *  Created on: 2016年6月8日
 *      Author: 龙叔
 */

#include <stdio.h>
#include "SLNode.h"

/*
 * 链表测试
 */
void test_SLNode() {
    SLNode *head;
    InitSLNode(&head);
    for (int i = 97; i < 107; ++i) {
        SLNodeAdd(head, i);
    }
    ShowSLNode(head);
    SLNodeInsert(head, 1, 'I');
    ShowSLNode(head);
    SLNodeUpdate(head, 1, 'A');
    ShowSLNode(head);
    int index = SLNodeSearch(head, 'A');
    printf("index A : %d \n", index);
    SLNodeRemove(head, 1, NULL);
    ShowSLNode(head);
    SLNodeDestroy(&head);
    ShowSLNode(head);
}

int main() {
    test_SLNode();
    return 0;
}

运行结果


ShowSLNode:
a b c d e f g h i j
ShowSLNode:
a I b c d e f g h i j
ShowSLNode:
a A b c d e f g h i j
index A : 2
ShowSLNode:
a b c d e f g h i j
ShowSLNode:


转载于:https://www.cnblogs.com/longshu/p/6818131.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值