08.数据结构学习2.0

08.数据结构学习2.0

1、链表

1、链表的构成:

img

节点:数据+指向下一个节点的指针

#define ElementType int
struct Node
{
    ElementType data;//存放数据
    struct Node* next;//指向下一节点的指针,里面存放的是地址
};
struct LinkList
{
    struct Node *head;//定义头节点
    int len;//记录链表长度
};

2、特点:插入和删除比较方便,不利于随机存放

3、链表的初始化:

int InitLinList(struct LinkList *list)
{
    //给头节点申请空间
    list->head = (struct Node *)malloc(sizeof(struct Node));
    if(list->head == NULL)
    {
        printf("InitLinkList malloc Error!\n");
        return false;
	}
    list->head->data = 0;
    list->head->next = NULL;
    
    return true;
}

4、链表的操作:

(1)、封装一个函数实现创建新节点

struct Node* CreateNode(ElementType element)
{
    //给一个新节点申请空间
    struct Node *NewNode = (struct Node *)malloc(sizeof(struct Node));
    if(NewNode == NULL)//判断申请节点是否成功
    {
        printf("CreateNode malloc error!\n");//申请失败,则打印错误信息,返回;
        return NULL;
    }
    NewNode->data = element;//给新节点指向的数据赋值
    NewNode->next = NULL;//next指向空
    return NewNode;
}

(2)、释放链表所有节点

void FreeLinkList(struct LinkList *list)
{
    struct Node *TravelPoint = list->head->next;//申请一个节点指向头节点
    while(TravelPoint != NULL)//当头结点的下一节点不为空,一直释放一个往后挪一个
    {
        free(list->head);//释放头节点
        list->head = TravelPoint;//让头节点指向原来的下一个
        TravelPoint = list->head->next;//头节点的下一个节点也更新
    }
    free(list->head);//最后剩下一个头节点给他释放
    list->head = NULL;//头节点指向空
    list->len =0;//长度为0
}

(3)、遍历输出链表

void Travel(struct Node* list)
{
    struct Node *TravelPoint = list->head->next;//设置一个遍历指针指向头指针的下一个节点
    while(TravelPoint != NULL)//当下一个不为空的时候
    {
        printf("%d ",TravelPoint->data);//输出内容
        TravelPoint = TravelPoint->next;//指针指向下一个
    }
    printf("\n");
}

(4)、增加链表

【1】、尾插法

void InsertTail(struct LinkList *list,ElementType element)
{
    //创建一个新节点里面存要插入的值
    struct Node *NewNode = CreateNode(element);
    if(NewNode == NULL)//判断新节点是否申请成功
    {
        printf("InsertTail CreateNode Error!\n");//失败打印错误信息,返回;
        return ; 
    }
    struct Node * TravelPoint = list->head;//设置一个遍历指针指向头节点
    while(TravelPoint->next != NULL)//判断当前节点是否已经是最后一个节点
    {
        TravelPoint = TravelPoint->next;//不是,则向后移,直到找到最后一个节点
    }
    TravelPoint->next = NewNode;//将最后一个节点指向新节点
    list->len++;//长度加一
}

【2】、头插法

void InsertHead(struct LinkList *list,ElementType element)
{
    //创建一个新节点里面存要插入的值
    struct Node *NewNode = CreateNode(element);
    if(NewNode == NULL)//判断新节点是否申请成功
    {
        printf("InsertTail CreateNode Error!\n");//失败打印错误信息,返回;
        return ; 
    }
    NewNode->next = list->head->next;//新节点指向头节点的下一个节点
    list->head->next = NewNode;//头节点指向新节点
    list->len++;//长度加一
}

【3】、按位序插入

void InsertIndex(struct LinkList *list,ElementType element,int index)
{
    if(index < 0 || index > list->len)//判断插入数据位置是否合法
    {
        printf("InsertIndex illegal place!\n");//不合法打印错误信息,返回;
        return ;
    }
    struct Node *NewNode = CreateNode(element);//申请创建新节点
    if(NewNode == NULL)//判断申请新节点是否成功
    {
        printf("InsertIndex CreateNode Error!\n");//申请失败,打印错误信息返回;
        return;
    }
    struct Node *TravelPoint = list->head;//申请一个遍历指针指向head
    while(index != 0)//找到要插入的位置,index从0开始数
    {
        TravelPoint = TravelPoint->next;//向后挪直到找到该位置
        index--;
    }
    NewNode->next = TravelPoint->next;
    TravelPoint->next = NewNode;
    list->len++;
}

(5)、删除节点

【1】、按位序删除

void RemoveByIndex(struct LinkList *list,int index)
{
    if(index < 0 || index >= list->len)//判断插入数据位置是否合法
    {
        printf("RemoveByIndex illegal place!\n");//不合法打印错误信息,返回;
        return ;
    }
    struct Node *TravelPoint = list->head;//申请一个遍历指针指向head
    while(index != 0)//找到要插入的位置,index从0开始数
    {
        TravelPoint = TravelPoint->next;//向后挪直到找到该位置
        index--;
    }
    struct Node *FreeNode = TravelPoint->next;//设置要删除的节点
    TravelPoint->next = FreeNode->next;
    free(FreeNode);//释放要删除的节点
    list->len--;//长度减一
}

【2】、按值删除

void RemoveByElement(struct LinkList *list,ElementType element)
{
    //设置一个遍历指针进行比较对比
    struct  Node* TravelPoint = list->head;
    while(TravelPoint->next != NULL)//判断节点的下一节点是否为空
    {
        if(TravelPoint->next->data == element)//判断是否为我们要找的值
        {
            struct Node *FreeNode = TravelPoint->next;//设置一个节点存放我们要删除的节点
            TravelPoint->next = FreeNode->next;//当前节点的后继指向下一节点的后继节点
            free(FreeNode);//释放要删除的节点
            list->len--;//长度减一
        }
        else
        {
            TravelPoint = TravelPoint->next;//如果当前节点的判断结束,则进入下一个节点判断
        }
    }
}

(6)、查找

【1】、按位查找

//int型返回值是没有办法去判断值是否是有有效值的,只有空指针才能表示返回值是否有效
ElementType *FindByIndex(struct LinkList *list, ElementType element, int index)
{
    if(index < 0 || index >= list->len)
    {
        printf("FindByIndex illegal place!\n");
        return NULL;
    }
    struct Node* TravelPoint = list->head;
    while(index != 0)
    {
        TravelPoint = TravelPoint->next;
        index--}
    return &TravelPoint->next->data;
}

【2】、按值查找

int *FindByElement(struct LinkList *list,ElementType element)
{
    //申请一个数组存放下对应找到的值的数组下标
    int *findVector = (int *)malloc(sizeof(int)*(list->len+1));
    if(findVector == NULL)//判断申请是否失败
    {
        printf("FindByElement malloc error!\n");//打印错误信息,返回NULL
        return NULL;
	}
    struct Node* TravelPoint = list->head;//从设置一个标志头节点开始,头节点没有数据所以判断从下一节点开始
    int count=0,k=0;//设置计数器
    while(TravelPoint->next!=NULL)//当下一个节点不为空的时候进入循环
    {
        if(TravelPoint->next->data == element)//判断下一节点的值是否等于要查找的值
        {
            findVector[k] = count;//存储当前下标
            k++;//新数组的下标加一
        }
        count++;//原数组的下标移动
        TravelPoint = TravelPoint->next;//进入下一个值的判断
    }
    findVector[k] = -1;//设置新数组的最后一位为标志位
    return findVector;
}

(7)、修改节点的值

【1】、按位置修改

void SetValuebyIndex(struct LinkList *list, ElementType element, int index)
{
    if (index < 0 || index >= list->len)
    {
        printf("SetValueByIndex illegal place!\n");
        return;
    }
    struct Node *TravelPoint = list->head;
    while (index != 0)
    {
        TravelPoint = TravelPoint->next;
        index--;
    }
    TravelPoint->next->data = element;
}

【3】、按值修改

void SetValueByElement(struct LinkList *list, ElementType oldValue, ElementType newValue)
{
    int *findVector = FindByElement(list,oldValue);
    if(findVector == NULL)
    {
        printf("Can't find any elements!\n");
        return ;
    }
    int *temp = findVerctor;
    while(*temp != -1)
    {
        SetValueByIndex(list,newValue,*temp);
        temp++;
    }
    free(findVerctor);
}

(8)、冒泡排序

void BubbleSort(struct LinkList *list)
{
    for(int i=0;i<list->len;i++)//记录当前扫描的次数
    {
        struct Node *TravelPoint = list->head;//设置一个遍历指针
        for(int j=0;j<list->len-i-1;j++)//开始扫描交换
        {
            //判断两个节点值的大小,小则交换
            if(TravelPoint->next->data < TravelPoint->next->next->data)
            {
                struct Node *Prev = TravelPoint->next;
                struct Node *Next = TravelPoint->next->next;
                Prev->next = Next->next;
                Next->next = Prev;
                TravelPoint->next = Next;
            }
            TravelPoint =TravelPoint->next;
        }
	}
}

(9)、逆序输出

【1】、非递归

void Reserve(struct LinkList *list)
{
    struct Node *prev = NULL;
    struct Node *cur = list->head->next;
    struct Node *Next = cur->next;
    while(Next != NULL)
    {
        cur->next = prev;
        prev = cur;
        cur = Next;
        Next = cur->next;
	}
    cur->next = prev;
    list->head->next = cur;
}

【2】、递归

struct Node *Reserve2(struct Node *node)
{
    struct Node * tail;
    if(node->next!=NULL)
    {
        tail = Reserve2(node->next);
        node->next->next = node;
        node->next = NULL;
        return tail;
    }
    return node;
}

(10)、合并链表

img

struct LinkList *Mergelist(struct LinkList *list1,struct LinkList *list1)
{
    BubbleSort(list1);
    BubbleSort(list2);

    struct LinkList* list3 = (struct LinkList *)malloc(sizeof(struct LinkList));
    if(list3 == NULL)
    {
        printf("MergeList malloc error!\n");
        return NULL;
    }
    InitLinkList(list3);
    list3->len = list1->len + list2->len;
    struct Node * TravelPoint = list3->head;
    list1->head=list1->head->next;
    list2->head=list2->head->next;
    while(list1->head != NULL && list2->head != NULL)
    {
        if(list1->head->data < list2->head->data)
        {
            TravelPoint->next = list1->head;
            list1->head = list1->head->next;
        }
        else
        {
            TravelPoint->next = list2->head;
            list2->head = list2->head->next;
        }
        TravelPoint = TravelPoint->next;
    }
    if(list1->head != NULL)
    {
        TravelPoint->next = list1->head;
    }
    if(list2->head != NULL)
    {
        TravelPoint->next = list2->head;
    }
    return list3;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值