chapter two 2-7单链表删除元素操作、删除单链表整个表

2-7单链表删除元素操作、删除单链表整个表

全局数据结构头文件(见上篇文章)

上一篇里也有链表的超多操作哦

单链表头文件 linklist.h
#ifndef LINKLIST_H_INCLUDED
#define LINKLIST_H_INCLUDED

/***********************************************************************
 *  Project:数据结构第二章案例
 *  Function:链表抽象数据类型的定义和实现
 *  Description:每个节点都有后继结点,链表的优点是存储空间利用高效
 *  Author:chillinght
 *
 ***********************************************************************
 *  Copyright:2019 by chillinght
 ***********************************************************************
 */

 #include <stdio.h>
 #include <stdlib.h>
 #include "DataElement.h"
 #include <stdbool.h>

 /** 定义链表的结点,包含数据域和指针域  */
 typedef  struct Node{
    ElementType data;           //数据域
    struct Node* next;  //指针域,指向下个结点
 }Node;

 //注意这里定义了链表的结点结构 //但是没有头结点,有时,我们为了更加方便地对链表进行操作,会在单链表的第一个结点前附设一个结点,称为头结点。头结点的数据域可以不存储任何信息,谁叫它是第一个呢,有这个特权。也可以存储如线性表的长度等附加信息,头结点的指针域存储指向第一个结点的指针
/**
 * 下面的结构是用来存储指向第一个非头结点指针和链表长度的
 * 头结点
 * 也叫首元结点,最后一个结点也叫尾元结点,
 * 习惯性的定义头结点,以便统一结点的插入和删除
 */
 typedef struct LinkList{
    Node* next ;                //指针域  也就是头指针(如果有头结点,next指向头结点,没有就指向第一个结点)
    int length;                 //数据域
 }LinkList;

 /** 初始化链表 */
 void InitLinkList(LinkList * linkList,ElementType* dataArray,int length);

  /** 插入方法 */
 void InsertLinkList(LinkList* linklist,ElementType element,int pos);


  /** 打印方法 */
void PrintLinkList(LinkList* linkList);

/** 判断是否为空 */
int IsLinkListEmpty(LinkList* linklist);

/** 查询返回pos位置的元素 */
ElementType GetLinkListElement(LinkList* linklist,int pos);

/** 删除pos位置的元素 返回元素内容 */
ElementType DeleteLinkListElement(LinkList* linkList,int pos);

/** 清空链表 */
void ClearLinkList(LinkList* linklist);
#endif // LINKLIST_H_INCLUDED

实现文件 linklist.c
#include "LinkList.h"


 /** 初始化链表 */
void InitLinkList(LinkList * linkList,ElementType* dataArray,int length)
{
    for(int i= 1;i <= length;i++){
        InsertLinkList(linkList,dataArray[i-1],i);
    }
    return;
}


/** 插入方法 在pos前面插入*/
/**
 * 向链表插入元素
 * @param linklist      指向头结点的指针-》头指针(头指针指 指向第一个元素的指针,这里第一个元素是头结点)
 * @param element       插入元素  这里的元素是Node结点数据类型中的数据域内容
 * @param pos           插入位置
 */
 void InsertLinkList(LinkList* linklist,ElementType element,int pos)
 {
    //1. 创建空间存储新节点信息
    Node* new_node = (Node*)malloc(sizeof(Node));
    new_node->data = element;
    new_node->next = NULL;
    //2. 找到要插入的位置
    if(pos == 1){                           //如果插入的是第一个元素,由于linklist和node数据结构不一样 需要单独写一下
        new_node->next = linklist->next;
        linklist->next = new_node;
        linklist->length ++;
        //printf("%d\n",linklist->length);
        return;
    }
    // 下面正式开始找位置(pos之前元素的位置)
    Node* p = linklist->next;               //p指向第一个元素
    for(int i = 1;p &&i < pos - 1;i++){
        p = p->next;
    }
    //3.如果能够插入,开始定义结点空间并改变指针域进行连接
    if(!p){//如果pos位置的结点不存在
        printf("该位置不存在\n");
        return;
    }
    else{
        new_node->next = p->next;
        p->next = new_node;
        //现在p已经没用了,已经连上了~ 可以删了p了 别忘了总长度
        p = NULL;
        linklist->length++;
        //printf("%d\n",linklist->length);
        return;
    }

 }
void PrintLinkList(LinkList * linkList)
{
    Node* p = linkList->next;
    if(!p){
        printf("链表为空\n");
        linkList->length = 0;
        return;
    }
    //printf("%d\n",linkList->length);
    while(p)
    {
        printf("%d\t%s\n",p->data.id,p->data.name);
        p = p->next;

    }
    //p = NULL;
    return;
}

int IsLinkListEmpty(LinkList* linklist)
{
    return linklist->length == 0 ? true : false;
}

ElementType GetLinkListElement(LinkList* linklist,int pos)
{
    Node* p = linklist->next;
    for(int i = 1;p && i < pos;i++){
        p = p->next;
    }
    return p->data;
}

ElementType DeleteLinkListElement(LinkList* linkList,int pos)
{
    //删除其实很简单
    //1.判断pos是否合法 不合法直接gg
    //2.指定两个结点指针,分别指向要删除的结点和它上一个结点:这里注意如果是第一个元素,就没有前一个结点(头结点不算)
    //3.如果不是第一个元素,那就按照正常逻辑删除就ok
    printf("删除元素中\n");
    if(pos > linkList->length){
        printf("pos不合法,该位置元素无法删除\n");
        return;
    }
    else{   //合法
        Node* pre_node;
        Node* del_node = linkList->next;
        if(pos == 1){
            linkList->next = del_node->next;
            free(del_node);
            linkList->length--;
        }
        else{
            for(int i = 1;i < pos;i++)
            {//把指针位置弄好
                pre_node = del_node;
                del_node = del_node->next;
            }
            ElementType ret_element;
            del_node->data = ret_element;
            pre_node->next = del_node->next;
            free(del_node);
            linkList->length--;
            return ret_element;
        }
    }
}

void ClearLinkList(LinkList* linklist)
{
    printf("开始删除整个单链表\n");
    Node* p;
    Node* q;
    p = linklist->next;
    while(p){
        q = p->next;
        free(p);
        p = q;
    }
    linklist->next = NULL;
    linklist->length = 0;
    printf("删除完成\n");
    return;
}

测试文件
#include <stdio.h>
#include <stdlib.h>
#include "SequenceList.h"
#include "DataElement.h"
#include "LinkList.h"
//测试一下~
void TestSequenceList();
void TestLinkList();

int main()
{
    //TestSequenceList();
    TestLinkList();
    return 0;
}
void TestSequenceList()
{
    ElementType dataArray[] = {
    {1,"海绵宝宝"},
    {2,"派大星"},
    {3,"章鱼哥"},
    {4,"蟹老板"},
    {5,"痞老板"}
    };
    SeqList seqlist;
    InitList(&seqlist,dataArray,sizeof(dataArray) / sizeof(dataArray[0]));
    PrintList(&seqlist);
    //下面进行删除操作测试
    int del = -1,get = -1;
    printf("下面进行删除操作测试\n请输入删除元素的索引值:");
    scanf("%d",&del);
    ElementType* del_element = DeleteElement(&seqlist,del);
    printf("删除之后的结果为:\n");
    PrintList(&seqlist);
    printf("所删除的元素是:%d\t%s\n",del_element->id,del_element->name);
    printf("请输入要查找的元素的索引:");
    scanf("%d",&get);
    ElementType* get_element = GetElement(&seqlist,get);
    printf("您所查找的元素为:%d\t%s:",get_element->id,get_element->name);
    free(del_element);
}
void TestLinkList()
{
    ElementType dataArray[] = {
    {1,"海绵宝宝"},
    {2,"派大星"},
    {3,"章鱼哥"},
    {4,"蟹老板"},
    {5,"痞老板"}
    };
    LinkList linklist;
    linklist.length = 0;
    linklist.next = NULL;
    //printf("%d\n",sizeof(dataArray)/sizeof(dataArray[0]));
    InitLinkList(&linklist,dataArray,sizeof(dataArray)/sizeof(dataArray[0]));
    PrintLinkList(&linklist);
    printf("\n");
    ElementType new_node_element;
    new_node_element.id = 6;
    new_node_element.name = "xxxxx";
    InsertLinkList(&linklist,new_node_element,2);

    PrintLinkList(&linklist);
    printf("是否为空?\t%d\n",IsLinkListEmpty(&linklist));
    printf("第3位元素为%d\t%s\n",GetLinkListElement(&linklist,3));
    ElementType del_data;
    del_data = DeleteLinkListElement(&linklist,3);
    printf("删除的元素为%d\t%s\n",del_data.id,del_data.name);
    PrintLinkList(&linklist);

    ClearLinkList(&linklist);
    PrintLinkList(&linklist);
    return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值