数据结构之单链表 C++实现

1.实现一个单链表的定义,生成,长度计算和元素的显示。

#include"iostream"

using namespace std;

typedef struct student{
    int data;
    student *next;
    student(int x) :data(x), next(NULL){}
}ListNode;

/*
生成一个单链表
*/
ListNode* creatList(){
    ListNode *head ,*cur, *temp;
    int x, cycle = 1;
    head = (ListNode*)malloc(sizeof(ListNode));//给head节点分配一个ListNode大小的内存空间
    cur = head;
    while (cycle){//输入数据已0作为链表的结束
        cout << "please input data:" << endl;
        scanf("%d", &x);
        if (x){
            temp = (ListNode*)malloc(sizeof(ListNode));
            temp->data = x;
            cur->next = temp;
            cur = temp;
        }
        else{
            cycle = 0;
        }
    }
    head = head->next;
    cur->next = NULL;
    return head;
}

/*
求链表的长度
*/
int listLength(ListNode *head){
    ListNode *temp = NULL;
    temp = head;
    int len = 0;
    while (temp){
        temp = temp->next;
        len++; 
    }
    return len;
}

/*
打印出链表的长度及元素
*/
void printList(ListNode *head){
    ListNode *temp;
    int len;
    len = listLength(head);
    cout << "There are " <<len<< " records are: " << endl;
    temp = head;
    while (temp){
        cout << temp->data <<" ";
        temp = temp->next;
    }
}

int main(){
    ListNode *head = creatList();
    printList(head);
    system("pause");
    return 0;
}

运行结果如下图所示:
这里写图片描述

2.增加删除节点功能
此时分三种情况,(1)当删除的是第一个节点时的情况,(2)当删除时中间节点的情况,包括最后一个节点的情况,(3)当需要删除的节点不在此链表中时,则直接返回原链表。
当时第一种情况时,只需要将指向第一个节点的指针指向下一个节点即可;当第二种情况时,则之前需要保存当前删除节点的前一个节点,让这个节点指向删除节点的下一个节点即可。
代码如下:

/*
删除节点
*/
ListNode* delListNode(ListNode *head,int num){
    ListNode *pre, *cur;
    pre = NULL;
    cur = head;
    while (num != cur->data && cur->next){
        pre = cur;
        cur = cur->next;
    }
    if (num == cur->data){
        if (cur == head){
            head = cur->next;
            free(cur);
        }
        else{
            pre->next = cur->next;
            free(cur);
        }
    }
    else{
        cout << num << " could not been found" << endl;
    }
    return head;
}

int main(){
    ListNode *head = creatList();
    printList(head);
    ListNode *h2 = delListNode(head, 5);
    printList(h2);
    system("pause");
    return 0;
}

现象如下所示:
这里写图片描述
这里写图片描述

3.增加链表排序功能
代码如下:

/*
排序,使用冒泡法进行升序排序
*/
ListNode* sortList(ListNode *head){
    ListNode *cur;
    if (!head || head->next == NULL) return head;
    int len = listLength(head);
    int temp = 0;
    cur = head;
    for (int i = 1; i < len; i++){//只需进行len-1次for循环
        cur = head;
        for (int j = 0; j < len - i; j++){//每执行一次for就可以将最大的数移到后面到正确位置,所以每次只需要进行len-i次for循环
            if (cur->data > cur->next->data){
                temp = cur->data;
                cur->data = cur->next->data;
                cur->next->data = temp;
            }
            cur = cur->next;
        }
    }
    return head;
}

int main(){

    ListNode *head = creatList();
    printList(head);
    //ListNode *h2 = delListNode(head, 5);
    //printList(h2);
    ListNode *h3 = sortList(head);
    printList(h3);
    system("pause");
    return 0;
}

现象如下所示:
这里写图片描述

4.增加插入节点功能
假设所给链表是已经按升序排好序的链表,给定一个值,将其插入到链表中,使链表仍然是有序的
插入时分三种情况:
(1)当插入节点值是最小的,则直接放在链表的最前面;
(2)当插入节点值既不最大也不最小,则放在链表中的正确位置上;
(3)当插入节点值时最大的,则放在链表的最后。

代码如下:

/*
插入节点
*/
ListNode* insertListNode(ListNode *head, int num){
    ListNode *temp,*pre, *cur;
    temp = (ListNode*)malloc(sizeof(ListNode));
    temp->data = num;
    cur = head;
    pre = NULL;
    while (temp->data > cur->data && cur->next){
        pre = cur;
        cur = cur->next;
    }
    if (temp->data <= cur->data){
        if (cur == head){
            temp->next = cur;
            head = temp;
        }
        else{
            pre->next = temp;
            temp->next = cur;
        }
    }
    else{
        cur->next = temp;
        temp->next = NULL;
    }

    return head;
}

int main(){

    ListNode *head = creatList();
    printList(head);
    //ListNode *h2 = delListNode(head, 5);
    //printList(h2);
    ListNode *h3 = sortList(head);
    printList(h3);
    ListNode *h4 = insertListNode(h3, 6);
    printList(h4);
    system("pause");
    return 0;
}

现象如下图所示,三种情况的现象图都已给出。
这里写图片描述
这里写图片描述
这里写图片描述

4.增加链表的逆置功能
思路:每次保存三个节点pre,cur,next,改变前两个节点pre和cur的指针指向,之后重新保存三个节点,此时cur变成pre,next变成cur,next->next变成next。

代码如下:

/*
链表逆置
*/
ListNode* reverseList(ListNode *head){
    ListNode *pre, *cur,*next;
    if (!head || head->next == NULL) return head ;
    pre = head;
    cur = pre->next;
    while (cur){
        next = cur->next;
        cur->next = pre;
        pre = cur;
        cur = next;
    }
    head->next = NULL;
    head = pre;
    return head;
}

int main(){

    ListNode *head = creatList();
    printList(head);
    //ListNode *h2 = delListNode(head, 5);
    //printList(h2);
    /*ListNode *h3 = sortList(head);
    printList(h3);
    ListNode *h4 = insertListNode(h3, 6);
    printList(h4);*/
    ListNode *h5 = reverseList(head);
    printList(h5);
    system("pause");
    return 0;
}

现象如下图所示:
这里写图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值