线性链表的基本操作(删除,插入等)

主要内容如题,由于感觉自己对链表这块的知识真的很薄弱.

我之前还时不时的去看链表相关的知识,也算是复习把,但是效果不尽人意.

时间可以淡忘一切,有的很慢,有的很快,而我感觉自己对链表的学习则是一瞬的时间.

哈哈,当然也没有这么夸张啦.

还是觉着把单链表的基本操作自己再撸一遍,这个感觉很有必要.

果然在编写的过程中发现很多问题,不过好在有些不太好理解的部分后面在草稿纸上画了一下才顺利编写出对应的代码.

 

我把代码贴上来也方便失忆后的恢复对链表的记忆.我估计后面自己看代码都有可能看不太明白.

 

以下便是自己实现的代码,估计会有很多毛病,但我自测的时候暂时没出现bug:

#include<stdio.h>
#include<stdlib.h> //malloc

typedef struct Node{
    int data;
    struct Node *next;
}Node;

void print(Node *head)//打印
{
    Node *p;

    if (!head) return;

    p = head;

    while(p){
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
}

Node *add_tail(Node *head)//尾插
{
    Node *p;
    int num = 0;

    if (!head) return     NULL;

    p = head;

    while (p->next) {
        p = p->next;
    }

    printf("\nhow many Node do you want to add?(tail_insert):");
    scanf("%d", &num);

    while (num-- > 0) {
        Node *new = (Node *)malloc(sizeof(Node));
        printf("input your data for new Node:");
        scanf("%d", &new->data);
        p->next = new;
        new->next=NULL;
        p = new;
    }
    return head;
}

Node *add_head(Node *head)//头插
{
    int num = 0;

    if (!head) return NULL;

    printf("\nhow many Node do you want to add?(head_insert):");
    scanf("%d", &num);
    while (num-- > 0) {
        Node *new = (Node *)malloc(sizeof(Node));
        printf("input your data for new Node:");
        scanf("%d", &new->data);
        new->next = head;
        head = new;
    }
    return head;
}

Node *del_pos(Node *head)//根据位置删除对应结点
{
    Node *p, *del;
    int count = 1;
    int pos = 0;

    if (!head) return NULL;

    printf("\ninput your delete‘s position:");
    scanf("%d", &pos);    

    p = head;

    if (pos == 1) {//pos 为 1 时 先把下一个结点作为头结点 并free掉原来的头结点 返回新头
            head = p->next;
            free(p);
            return head;
    }

    while(p && (count++) != (pos - 1)) {
        p = p->next;
    }
    if (count == pos) {
        del = p->next;
        p->next = del->next;
        free(del);
    } else { printf("out of rang!\n");}
    return head;
}

Node *del_data(Node *head)//根据元素删除对应结点
{
    Node *tmp, *p, *n;
    int data = 0;
    int count = 0;//统计结点受影响数    

    if (!head) return NULL;

    printf("\ninput your delete‘s data:");
    scanf("%d", &data);    

    p = head;
    n = head->next;

    while (n) {
        if (n->data == data) {
            p->next = n->next;
            free(n);
            n = p->next;
            count++;
            continue;
        }
        p = p->next;
        n = p->next;
    }
    if (head->data == data) {//头结点需要另外处理
        tmp = head;
        head = tmp->next;
        free(tmp);
        count++;
    }
    printf("%d rows effected!\n", count);
    return head;
}

Node  *insert(Node *head)//插入结点
{
    Node *p, *new;
    int count = 1;
    int pos = 0;

    if (!head) return NULL;

    printf("\ninput your insert‘s pos:");
    scanf("%d", &pos);

    p = head;

    new = (Node *)malloc(sizeof(Node));

    if (pos == 1) {//pos 为 1 时 进行头插
            printf("input your data for new Node:");
            scanf("%d", &new->data);
            new->next = head;
            head = new;
            return head;
    } 

    while(p && (count++) != (pos - 1)) {
        p = p->next;
    }

    if (count == pos) {
            printf("input your data for new Node:");
            scanf("%d", &new->data);
            new->next = p->next;
            p->next = new;
    } else { printf("out of rang!\n");}

    return head;

}

int clean(Node *head)//释放资源
{
    Node *p;

    if (!head) return 0;
    p = head;
    while(p) {
        free(p);
        p = p->next;

    }
    return 1;
}

int main()
{
    Node *n = (Node *)malloc(sizeof(Node));    //定义一个头结点
    Node *tmp;//临时结点

    int count = 3;    

    n->data = 2;
    n->next = NULL;

    print(add_tail(n));

    tmp = add_head(n);
    print(tmp);

    while (count-- > 0) {//根据位置删除
        tmp = del_pos(tmp);
        print(tmp);
    }

    count = 3;

    while (count-- > 0) {//插入
        tmp = insert(tmp);
        print(tmp);
    }

    count = 3;

    while (count-- > 0) {//根据结点数据删除
        tmp = del_data(tmp);
        print(tmp);
    }

    if (clean(tmp)) printf("clean up\n");
    else printf("it‘s empty! clean error!\n");
}

以下便是我在linux平台测试的结果:

我算是新手咯,如果有人点进来看到我写的代码,还请大大们多多指点代码的不足之处.

时间: 2024-11-05 08:55:02

线性链表的基本操作(删除,插入等)的相关文章

从新定义线性链表及其基本操作

链表在空间的合理利用上和插入.删除时不需要移动等优点,因此在很多场合下,它是线性表的首先储存结构.然而它也存在着实现某些基本操作,如求线性表的长度时不如顺序储存结构的特点.因而从新定义线性链表及其基本操作 头文件: #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define MYOVERFLOW -2 typedef int Status; typedef int Elemty

数据结构学习之单向链表的基本操作(非递归实现)

[摘要]本文讨论的均为带头结点的线性链表的基本操作,包括创建.删除.插入.打印等等,欢迎大家批评指正错误. (1)单链表存储结构 typedef struct LNode { int data; struct LNode *next; }LinkList; (2)创建链表 /* 功能:构建一个空的带头节点的单链表*/ Status InitList (struct LNode **L) { (*L) = (struct LNode *)malloc(sizeof(struct LNode));

线性链表的双向链表——java实现

.线性表链式存储结构:将采用一组地址的任意的存储单元存放线性表中的数据元素. 链表又可分为: 单链表:每个节点只保留一个引用,该引用指向当前节点的下一个节点,没有引用指向头结点,尾节点的next引用为null. 循环链表:一种首尾相连的链表. 双向链表:每个节点有两个引用,一个指向当前节点的上一个节点,另外一个指向当前节点的下一个节点. 下面给出线性表双向链表的实现:java中LinkedList是线性表的链式实现,是一个双向链表. import java.util.NoSuchElementE

线性单链表的初始化、插入、删除功能实现

1 ////////////////////////////////////////////////////////// 2 // singlelist.cpp 3 // 4 // author:Leetao 5 ////////////////////////////////////////////////////////// 6 // 简介: 7 // 线性链表的实现 8 ////////////////////////////////////////////////////////// 9

数据结构:链表的基本操作(创建,删除,插入,逆序,摧毁)

代码注释比较详细: #include <iostream> #include <cstdlib> using namespace std; struct Node{ int data; Node* next; }; Node* head = NULL; bool create() { head = (Node*)malloc(sizeof(Node)); if(NULL == head) return false; head->data = 0; head->next

链表的创建,插入,删除,输出基本操作

#include<stdio.h>#include<cstdlib> struct student  //定义一个学生结点,结点包括值域和指针域{ int num;//学号 char name[20];//姓名 char address[20];//地址 struct student *next;//定义结点的指针域,指向下一个结点};typedef struct student LIST;LIST *CreateList();LIST *InsertNode(LIST *h,LI

头插法链表的基本操作:创建空链表,插入结点,遍历链表,求链表长度,查找结点,删除结点

1 #include <stdio.h> 2 #include <stdlib.h> 3 /* 4 头插法链表的基本操作:创建空链表,插入节点,遍历输出节点数据,求链表长度,查找结点,删除结点. 5 */ 6 typedef struct node 7 { 8 int data; 9 struct node * next; 10 }NODE; 11 //创建空链表 12 NODE * createList() 13 { 14 NODE * head = (NODE *)malloc

链表的基本操作:创建、插入、删除

#include<iostream> using namespace std; //链表的定义 struct ListNode { int val; ListNode* next; ListNode(int n) :val(n), next(nullptr) {} }; //链表的打印 void printList(ListNode* head) { ListNode* pT = head; while (pT != nullptr) { cout << pT->val &l

利用线性链表基本操作完成两个有序线性表的合并

La.Lb线性链表升序排列,将结果放在Lc链表里.之前有文章写过两个有序链表的合并 区别在于,前面的做法是保留La的头节点,free掉Lb的头节点,将余下节点串起来.这种方法是面向过程编程 而现在讨论的做法,是单独建立一个Lc链表,利用一些已经写好的基本操作函数来完成,这种模块化编程做法实际上还简单些.不光模块函数里写不了几行,在调用这些函数时减少了不必要的琐碎过程的思考时间. 该做法的核心思想:将每轮比较过后偏小的那个节点从相应链表中删除(这是头节点的指针不会指向该节点了,但该节点的空间依旧保