单链表的实现

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

在本文中单链表都使用了头节点来简化操作,头指针head指向头结点。链表由头指针唯一确定,单链表可以用头指针的名字来命名。

#include <iostream>

using namespace std;

#define ElemType int

typedef struct LNode {
    ElemType data;
    struct LNode *next;
} LNode, *LinkList;

void PrintList(LinkList L);

/**
 * 按位插入
 * @param L
 * @param i 插入的位置
 * @param e 插入的值
 * @return
 */
bool ListInsert(LinkList &L, int i, ElemType e);

bool InsertNextNode(LNode *p, ElemType e);

/**
 * 实际上还是后插结点,只不过将新的结点的值与后插的值互换,达到逻辑上的前插
 * @param p
 * @param e
 * @return
 */
bool InsertBeforeNode(LNode *p, ElemType e);

/**
 * 头插法建立链表
 * @param L
 * @return
 */
LinkList Insert_Head(LinkList &L);

/**
 * 尾插法建立,顺序相同
 * @param L
 * @return
 */
LinkList Insert_Tail(LinkList &L);

/**
 * 按位删除,将删除后的数据返回
 * @param L
 * @param i
 * @param e
 * @return
 */
bool ListDelete(LinkList &L, int i, ElemType &e);

/**
 * 删除指定节点
 * @param p
 * @return
 */
bool DeleteNode(LNode *p);

LNode* GetElem(LinkList L, int i);



int main() {
    LinkList L;
    Insert_Tail(L);

    ListInsert(L, 2, 421);
    PrintList(L);
    cout << GetElem(L, 3)->data << endl;
    return 0;
}

bool ListInsert(LinkList &L, int i, ElemType e) {
    if (i < 1)
        return false;
    LNode *p = L;
    int j = 0;
    //遍历到前一个节点即可
    while (p != nullptr && j < i - 1) {
        p = p->next;
        j++;
    }
    if (p == nullptr)
        return false;
    LNode *lNode = (LNode *) malloc(sizeof(LNode));
    lNode->data = e;
    //插入代码,注意顺序不能写错!!!,否则新结点不能指向下一个结点
    lNode->next = p->next;
    p->next = lNode;
    return true;
}

bool InsertNextNode(LNode *p, ElemType e) {
    //判断传入指针是否为空指针
    if (p == nullptr)
        return false;
    LNode *lNode = (LNode *) malloc(sizeof(LNode));
    //判断内存分配是否成功
    if (lNode == nullptr)
        return false;
    lNode->data = e;
    lNode->next = p->next;
    p->next = lNode;
    return true;
}

bool InsertBeforeNode(LNode *p, ElemType e) {
    if (p == nullptr)
        return false;
    LNode *lNode = (LNode *) malloc(sizeof(LNode));
    if (lNode == nullptr)
        return false;
    lNode->next = p->next;
    p->next = lNode;
    lNode->data = p->data;
    p->data = e;
    return true;
}

LinkList Insert_Head(LinkList &L) {
    LNode *lNode;
    ElemType e;
    L = (LinkList) malloc(sizeof (LNode));
    L->next = nullptr;
    printf("请输入元素,输入999结束");
    scanf("%d", &e);
    while (e != 999) {
        lNode = (LNode *) malloc(sizeof (LNode *));
        lNode->data = e;
        lNode->next = L->next;
        L->next = lNode;
        scanf("%d", &e);
    }
    return L;
}

LinkList Insert_Tail(LinkList &L) {
    ElemType e;
    LNode *lNode;
    LNode *tail;
    L = (LinkList) malloc(sizeof (LNode));
    tail = L;
    printf("请输入元素,输入999结束");
    scanf("%d", &e);
    while (e != 999) {
        lNode = (LNode *) malloc(sizeof (LNode));
        lNode->data = e;
        //将新的指针置于尾指针后,并在插入完成后置为尾指针
        tail->next = lNode;
        tail = lNode;
        scanf("%d", &e);
    }
    //将尾指针置为空
    tail->next = nullptr;
    return L;
}

void PrintList(LinkList L) {
    LNode *p = L->next;
    while (p) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

bool ListDelete(LinkList &L, int i, ElemType &e) {
    if (i < 1)
        return false;

    LNode *p = L;
    int j=0;
    while (p!= nullptr && j<i-1) {
        p = p->next;
        j++;
    }

    if (p == nullptr || p->next == nullptr)
        return false;
    LNode *delNode = p->next;
    e = delNode->data;
    //最好别写p->next = p->next->next 这样不好释放内存
    p->next = delNode->next;
    //释放内存
    free(delNode);
    return true;
}

bool DeleteNode(LNode *p) {
    if (p == nullptr)
        return false;
    LNode *delNode = p->next;
    p->data = delNode->data;
    p->next = delNode->next;
    free(delNode);
    return true;
}

LNode* GetElem(LinkList L, int i) {
    if (i < 1)
        return nullptr;
    int j = 1;
    LNode *p = L->next;
    while (p!= nullptr && j < i) {
        p = p->next;
        j++;
    }
    return p;
}

//反转链表
LinkList reverseList(LinkList L) {
    LNode *curr = L->next;
    LNode *pre = nullptr;

    while (curr != nullptr) {
        LNode *temp = curr->next;
        curr->next = pre;

        pre = curr;
        curr = temp;
    }
    LNode *head = nullptr;
    //在此处加一个头节点,方便我们去调用PrintList函数
    head->next = pre;
    return head;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值