数据结构学习第二天

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

typedef int ElemType;

// 定义单链表节点结构
typedef struct node {
    ElemType data;
    struct node* next;
}Node;

// 初始化链表,创建头节点
Node* initList() {
    Node* head = (Node*)malloc(sizeof(Node));
    head->data = 0;       // 头节点数据通常不使用,此处初始化为0无影响
    head->next = NULL;    // 初始时头节点指向NULL
    return head;
}

// 头插法插入元素
int insertHead(Node* L, ElemType e) {
    Node* p = (Node*)malloc(sizeof(Node));
    p->data = e;          // 新节点数据赋值
    p->next = L->next;    // 新节点指向原首节点
    L->next = p;          // 头节点指向新节点
    return 1;
}

// 遍历并打印链表元素
void ListNode(Node* L) {
    Node* p = L->next;    // 跳过头节点
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

//单链表-尾插法
Node* gettail(Node* L)//找链表尾部
{
    Node* p = L;
    while (p->next != NULL)
    {
        p = p->next;
    }
    return p;
}

Node* insertTail(Node* tail, ElemType e)
{
    Node* p = (Node*)malloc(sizeof(Node));//后插的节点
    p->data = e;
    tail->next = p;
    p->next = NULL;
    return p;//p成为新的尾节点
}

int insertNode(Node* L, int pos, ElemType e)
{
    //用来保存插入位置的前驱节点
    Node* p = L;//创建p指针指向传入的链表
    int i = 0;
    
    //遍历链表找到插入位置的前驱节点
    while (i < pos - 1)
    {
        p = p->next;//寻找传入的位置
        i++;
        if (p == NULL) {
            return 0;
        }
    }
    //要插入的新节点
    Node* q = (Node*)malloc(sizeof(Node));
    q->data = e;
    q->next = p->next;
    p->next = q;
    return 1;
}

//单链表-删除节点
int deleteList(Node* L, int pos)
{
    Node* p = L;
    int i = 0;
    while (i < pos - 1)
    {
        p = p->next;
        i++;
        if (p->next == NULL) {
            printf("删除的位置错误\n");
            return 0;
        }

        Node* q = p->next;
        p->next = q->next;
        free(q);
        return 1;
    }
}

//单链表-获取链表长度
int Listlength(Node* L)
{
    Node* p = L;
    int len = 0;
    while (p != NULL)
    {
        p = p->next;
        len++;
    }
    return len;
}

//单链表-释放链表
void freeList(Node* L)
{
    Node* p = L->next;
    Node* q;
    while (p != NULL)
    {
        q = p->next;
        free(q);
        p = q;
    }
    L->next = NULL;
}

//使用双指针找到倒数第k个节点
int findNodeFS(Node* L,int k)
{
    int i;
    Node* fast=L->next;
    Node* slow=L->next;//快慢指针,fast先走k步后slow走,直到fast指向NULL,slow为倒数第k位置
    for(i=0;i<k;i++)
    {
        fast=fast->next;
    }
    while(fast!=NULL)
    {
        fast=fast->next;
        slow=slow->next;
    }
    printf("倒数第%d个节点的数为%d\n",k,slow->data);
}

//单链表反转
Node* reserveList(Node* head)
{
    Node* first= NULL;
    Node* second=head->next;//创建三个节点,first,second,third
    Node* third;
    
    while(second!=NULL)
    {
        third=second->next;
        second->next=first;//second节点指向first,实现链表反转
        first=second;
        second=third;//三个节点沿原方向移动一位,second继续反转指针
    }
    Node* hd=initList();
    hd->next=first;//创建头指针指向反转后的链表
}

//单链表-删除链表中间节点
int delMiddleNode(Node* head)
{
    Node* fast=head->next;//利用快慢指针,快的速度是慢的2倍,当快到NULL时慢的下一个节点就是链表中点
    Node* slow=head;
    while(fast!=NULL && fast->next!=NULL)
    {
        fast=fast->next->next;//快移动两位
        slow=slow->next;//慢移动一位
    }
    Node* q=slow->next;
    slow->next=q->next;//慢指针指向中点的下一个节点,从而释放掉中点q
    free(q);//采用中间q指针将链表中点删除
    return 1;
}

//链表重新排序
void reOrderList(Node* head)
{
    Node* fast=head->next;
    Node* slow=head;
    while(fast!=NULL && fast->next!=NULL)
    {
        fast=fast->next->next;
        slow=slow->next;
    }
    Node* first=NULL;
    Node* second=slow->next;
    slow->next=NULL;
    Node* third=NULL;
    while(second!=NULL)
    {
        third=second->next;
        second->next=first;
        first=second;
        second=third;
    }
    Node* p1=head->next;
    Node* q1=first;
    Node* p2,*q2;
    while(p1!=NULL && q1!=NULL)
    {
        p2=p1->next;
        q2=q1->next;
        
        p1->next=q1;
        q1->next=p2;
        
        p1=p2;
        q1=q2;
    }
}

//判断链表是否有环
int isCycle(Node* head)
{
    Node* fast=head;
    Node* slow=head;
    while(fast!=NULL && fast->next!=NULL)
    {
        fast=fast->next->next;
        slow=slow->next;
    }
    if(fast==slow){
        return 1;
    }
    return 0;
}

int main() {
    Node* list = initList();

//    //Node* tail = gettail(list);//???
//    insertHead(list, 50);
//    insertHead(list, 20);
//    insertHead(list, 10);
//    insertHead(list, 40);
//    insertHead(list, 30);
//
//    ListNode(list);  // 调用遍历函数,输出链表内容
//
//    insertNode(list, 2, 15);
//    ListNode(list);
//    
//    findNodeFS(list,4);
    
//    Node* tail=gettail(list);
//    tail=insertTail(tail,1);
//    tail=insertTail(tail,2);
//    tail=insertTail(tail,3);
//    tail=insertTail(tail,4);
//    tail=insertTail(tail,5);
//    tail=insertTail(tail,6);
//    ListNode(list);//1 2 3 4 5 6
//    
//    Node* reserve=reserveList(list);
//    ListNode(reserve);//6 5 4 3 2 1
    
    Node* tail=gettail(list);
    tail=insertTail(tail,1);
    tail=insertTail(tail,2);
    tail=insertTail(tail,3);
    tail=insertTail(tail,4);
    tail=insertTail(tail,5);
    tail=insertTail(tail,6);
    //tail=insertTail(tail,7);
    ListNode(list);//1 2 3 4 5 6 7
    
//    delMiddleNode(list);
//    ListNode(list);//1 2 3 5 6 7

    reOrderList(list);
    ListNode(list);
    return 0;
}

《数据结构(C 语言描述)》也许是全站最良心最通俗易懂最好看的数据结构课(最迟每周五更新~~)_哔哩哔哩_bilibili

老师讲的很好,很适合初学者,看一遍代码然后自己在手敲一遍在听老师讲一遍,效果很好。希望帮助到大家,也请大家多多支持这位up

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值