二、线性表

序言

单向链表(单链表)是线性表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始。

结构如下

插入逻辑

图解

code

//add to list end
bool insert_element_slist(Node *pHead, int pos, ELEMENT data) {
    Node *tempNode = pHead;
    if (pHead == NULL) {
        return false;
    }
    if (pos == 1) { //链表没有0位置.要找的是pos-1位置插入.所以pos-1特殊处理
        Node *newNode = malloc(sizeof(Node));
        newNode->next = tempNode->next;
        newNode->data = data;
        tempNode->next = newNode;
        return true;
    }
    tempNode = get_element_slist(tempNode, pos - 1);
    if (tempNode == NULL) {
        return false;
    }
    Node *newNode = malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = tempNode->next;
    tempNode->next = newNode;
    return true;
};

删除

图解

code

bool del_element_slist(Node *pHead, int pos, ELEMENT *pData) {
    if (pHead == NULL) {
        printf("del_element_slist head is null");
        return false;
    }
    if (pos == 1) {
        Node *freeNode = pHead->next;

        if (freeNode == NULL) {
            printf("del node  is null when pos = 1");
            return false;
        }
        pHead->next = freeNode->next;
        *pData = freeNode->data;
        free(freeNode);
        freeNode = NULL;
        return true;

    }
    PNode tempNode = pHead;
    //找pos-1个节点
    tempNode = get_element_slist(tempNode, pos - 1);
    if (tempNode == NULL) {
        return false;
    }
    //转移指针
    Node *freeNode = tempNode->next;
    if (freeNode == NULL) {
        return false;
    }
    tempNode->next = tempNode->next->next;
    *pData = freeNode->data;
    //释放
    free(freeNode);
    return true;
}

链表反转

图解

反转前
反转前

反转后

code


//反转链表   HEAD->A->B->C     C->B->A->HEAD此时 C变成HEAD.
// HEAD数据不计入链表.原来的HEAD没有数据.此时变成了数据位.
Node *reverse_slist(Node *pHead) {
    if (!pHead) {
        return NULL;
    }
    Node *pNow = pHead;  //逻辑的当前节点
    Node *pPre = NULL;  //逻辑的上一个节点
    Node *pNext = NULL;//逻辑的下一个节点
    Node *pTail = NULL;//用来保存最后一个反转的尾指针
    while (pNow != NULL) {
        pNext = pNow->next; //得到下一个节点
        if (pNext == NULL) { //如果为空.证明pNow是tail
            pTail = pNow;
        }
        pNow->next = pPre; //当前节点指向前一个节点.真正反转的操作.只有这一步.其余的都是循环的赋值
        pPre = pNow; //把pNow赋值给pPre.当成普通赋值即可.为了下一次pNow->next = pPre;做准备
        pNow = pNext;//当成普通变量赋值.pNext = pNow->next; //循环遍历链表
    }
    pHead->next = NULL;

    return pTail;

};

函数一览


void init_slist(PNode *pHead);


bool is_emppy_slist(Node *pHead);

bool insert_element_slist(Node *pHead, int pos, ELEMENT data);

bool del_element_slist(Node *pHead, int pos, ELEMENT *pData);

PNode get_element_slist(PNode pHead, int pos);

void clear_slist(Node *pHead);

void destroy_slist(Node *pHead);

int get_length_slist(Node *pHead);

void print_slist(Node *pHead);

Node *reverse_slist(Node *pHead);

Node *reverse_slist_plus(Node *pHead);

引用:
http://blog.youkuaiyun.com/xyh269/article/details/70238501
http://www.cnblogs.com/QG-whz/p/5170147.html

code地址:
https://github.com/HumorSmith/DataStructure/tree/master/link_list

实验通常涉及线性表的链式存储结构,这是一种非连续的数据结构,每个元素由值和指向下一个元素的指针组成。以下是单链表基础操作的简要说明: 1. **插入(Insertion)**:在指定位置插入新节点,需要找到该位置更新后续节点的指针。 2. **删除(Deletion)**:移除指定节点,分为头部删除(首节点)和中间/尾部删除,需要处理头节点的情况,保持链表的完整性。 3. **查找(Search)**:通过遍历链表,对比节点值找到目标节点,如果未找到则返回null。 4. **求表长(Length)**:计算链表中节点的数量,从头节点开始递归计数。 5. **置逆(Reversal)**:将链表中的节点顺序反转,通常采用迭代或递归的方式进行。 6. **有序链表(Merge of Sorted Lists)**:对于两个已排序的链表,合成一个新的有序链表,可以采用双指针法逐一比较节点大小进行合。 在实际编程中,这些操作通常会用到结构体或链表节点类,同时配合循环或递归来完成。下面是伪代码示例: ```cpp // 假设有一个链表节点结构体 Node void insert(Node* &head, int data, int position) { // 插入逻辑... } Node* deleteNode(Node* head, int key) { // 删除逻辑... } bool search(Node* head, int key) { // 查找逻辑... } int getLength(Node* head) { // 计算长度逻辑... } void reverseList(Node* &head) { // 反转逻辑... } Node* mergeSortedLists(Node* list1, Node* list2) { // 合逻辑... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值