单链表基本操作实现

单链表也是很朴素的数据结构,思想很简单。用next域存储下个节点。通常加一个头结点会很方便。

虽然不用移动大量元素,但是查找定位的时候必须顺着链表遍历,不能随机存储,时间复杂度还是O(n)。

优点是不需要来回分配存储空间,只需要按需存储,对于查询操作比较弱的需要,满足比较好。

代码也是很简单的,注释已经很清楚了。

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

using namespace std;

// 单链表的实现

typedef int ElemType;
typedef bool Status;
#define OK true;
#define FAIL false;

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

LinkList InitList() {
    LinkList head = new LNode();
    head->next = NULL;
    head->data = 0;  // 单链表头指针数据域存放链表长度

    return head;
}

Status CreateList(LinkList head, ElemType* data, int size) {
    LinkList pNode = head;
    for(int i=0; i<size; i++) {
        LinkList tmp = new LNode();
        tmp->next = NULL;
        tmp->data = data[i];

        pNode->next = tmp;
        head->data++;
        pNode = pNode->next;
    }

    return OK;
}

// index不是下标,是第几个
Status GetElem(LinkList head, int i, ElemType &e) {
    if(i<1 || i>head->data)
        return FAIL;

    LinkList pNode = head->next;
    int count(1);
    while(pNode) {
        if(count==i)
            break;

        pNode = pNode->next;
        count++;
    }
    e = pNode->data;

    return OK;
}

// 其实就是遍历顺序表,效率低下,按值查找通常要先排序
LinkList LocateElem(LinkList head, ElemType x) {
    LinkList pNode = head->next;
    while(pNode) {
        if(pNode->data == x)
            return pNode;
        pNode = pNode->next;
    }

    return NULL; // 没找到
}

Status ListInsert(LinkList head, int i, ElemType e) {
    if(i<1 || i>head->data+1)
        return FAIL;

    LinkList pNode = head->next;
    int count(1);
    while (pNode) {
        if (count == 1) {
            LinkList pNewNode = new LNode();
            pNewNode->data=e;

            pNewNode->next = pNode->next;
            pNode->next = pNewNode;
            head->data++;
            break;
        }

        pNode = pNode->next;
    }

    return OK;
}

Status ListDelete(LinkList head, int i, ElemType &e) {
    if(i<1 || i>head->data)
        return FAIL;

    LinkList pNode = head->next;
    LinkList prior = head;
    int count(1);
    while (pNode) {
        if(count==i)
            break;
        else
            prior = pNode;

        pNode = pNode->next;
        count++;
    }

    e = pNode->data;
    printf("%d %d %d\n", e, count, i);
    prior->next = pNode->next;
    delete pNode;
    head->data--;

    return OK;
}

void print(LinkList head) {
    cout<<"输出顺序表"<<endl;
    printf("Sqlist size: %d\n", head->data);
    LinkList pNode = head->next;
    while(pNode) {
        printf("%d\t", pNode->data);
        pNode = pNode->next;
    }

    cout<<endl;
}

void DestroyList(LinkList head) {
    LinkList pNode = head->next;
    while (pNode) {
        LinkList tmp = pNode;
        pNode = pNode->next;
        delete tmp;
    }

    head->next = NULL;
    head->data = 0;
}

// 由于用头结点的data存储长度信息,直接返回,如果没有的话,那需要遍历查找
int getLength(LinkList head) {
    if(head)
        return head->data;
    else
        return 0;
}

int main() {
    ElemType testCase[] = {
            6501,6828,6963,7036,7422,7674,8146,8468,8704,8717,9170,9359,9719,9895,9896,9913,9962,154,293,334,492,1323,
            1479,1539,1727,1870,1943,2383,2392,2996,3282,3812,3903,4465,4605,4665,4772,4828,5142,5437,5448,5668,5706,
            5725,6300,6335
    };
    int size = sizeof(testCase) / sizeof(ElemType);

    LinkList head = InitList();
    print(head);

    CreateList(head, testCase, size);
    print(head);

    printf("\nget element by index\n");
    for(int i=1; i<=size; i++) {
        int e;
        GetElem(head, i, e); // i是第几个,不是数组下标
        printf("%d: %d\t", i, e);
    }

    printf("\n\nget location of element\n");
    printf("index: %d\n", LocateElem(head, 12)!=NULL?LocateElem(head, 12)->data:-1);
    printf("index: %d\n", LocateElem(head, 9913)!=NULL?LocateElem(head, 9913)->data:-1);

    printf("\n\ninsert element\n");
    ListInsert(head, 5, 10);
    print(head);
    for(int i=0; i<100; i++)
        ListInsert(head, 5, i);
    print(head);

    printf("\n\n删除性测试\n");
    ElemType e;
    for(int i=1; i<=5; i++) {
        ListDelete(head, i, e); // i是第几个,不是数组下标
        printf("e: %d\n", e);
        print(head);
    }

    DestroyList(head);

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值