CSDN第一篇博客-C语言链表操作

一个小白的C语言学习成长

第一次写博客,也是一个小白,非计算机专业的小白,想通过一个平台慢慢提高自己,慢慢记录自己的成长,也希望CSDN社区的小伙伴们能够宽容我这样的小白,有什么不对的地方希望各位能见谅。

C语言实现链表的操作

用C语言首先构建链表的一系列的操作,其中包括链表的生成,链表的排序,链表的倒序,改变两两节点指向,头插法,尾插法等基本操作。直接上代码。代码中有详细的注解

#include 
#include
#if 0
头插法
1.让新来的节点,有所指向,新来的节点不会打断原有的指向关系
尾插法


#endif


#if 0
void test()
{
    Node a,b,c,d;
    a.data=1;
    b.data=2;
    c.data=3;
    d.data=4;
    Node *head=&a;
    a.next=&b;
    b.next=&c;
    c.next=&d;
    d.next=NULL;
    Node *p =head;
    while (p) {
        printf("%d\n",p->data);
        p=p->next;

    }
    Node *p1=head;
    Node *p2 =p1->next;
    Node *p3;
    while (p2) {
    p3=p2->next;
    p2->next=p1;
    p1=p2;
    p2=p3;
    }
    head->next=NULL;
    while (p1) {
        printf("%d\n",p1->data);
        p1=p1->next;

    }

}
#endif
typedef struct Link
{
    int data;
    struct Node * next;
}Node;
//创建一个空链表
Node * createLink()
{
   Node *head = (Node*)malloc(sizeof(Node));
   head->next=NULL;
   return head;
}
//头插法创建链表
Node * addHeadLink(Node*head)
{
    for (int i=0;i<10;i++)
    {
        Node *cur=(Node*)malloc(sizeof(Node));
        cur->data=rand()%100;
        cur->next=head->next;
        head->next=cur;
    }
    return head;


}
//判断一个链表的长度
int lenLink(Node *head)
{
    int len = 0;
    Node *p=head->next;

    while (p) {
        len+=1;
        p=p->next;

    }
    return len ;
}
//尾插法添加链表元素
Node * addEndLink(Node*head)
{
    Node *p = head;
    for(int i=0;i<10;i++)
    {
        Node *cur =(Node*)malloc(sizeof(Node));
        cur->data=rand()%80;
        cur->next=NULL;
        p->next=cur;
        p=p->next;

    }
    return head;
}
//指定位置插入链表元素
Node * addLink(Node*head,int n,int m)
{
    Node *cur =head;
    int num=0;
    while(num!=n-1)
    {
        cur=cur->next;
        num++;
    }
    Node *q=(Node*)malloc(sizeof(Node));
    q->data=m;
    q->next=cur->next;
    cur->next=q;
    return head;
}
//排序该表值法
void sortPopLink(Node *head,int len)
{
    for(int i=0; i<len-1; i++)
    {
        Node * r = head->next;
        for (int j=0;j<len-1-i;j++)
        {
            Node * p=r->next;
            if(r->data>p->data)
            {
                r->data=r->data^p->data;
                p->data=r->data^p->data;
                r->data=r->data^p->data;
            }
            r=r->next;
        }

    }

}
//排序改变地址法
void sortPopAdressLink(Node*head,int len)
{
    for (int i=0;i<len-1;i++)
    {
        Node *cur =head;
        Node *p = cur->next;
        Node *q =p->next;
        for (int j=0;j<len-1-i;j++)
        {
            if(p->data>q->data)
            {
              cur->next=p->next;
              p->next=q->next;
              q->next=p;
              Node *temp =p;//改变P和q的次序非常重要。第一次改变之后为cur->q->p;所以需要改变次序
              p=q;
              q=temp;

            }
            cur=cur->next;
            p=p->next;
            q=q->next;

        }
    }
}
//倒序eg 5->4->3->2->1->NULL  NULL->1->2->3->4->5
Node * inverseLink(Node *head)
{
    Node *p = head->next,*q;//先定义一个指针q存储
    head->next = NULL;//打断整个链表。创建一个空链表
    while(p != NULL)
    {
        q = p->next;//q先记录p的下一个节点
        p->next = head->next;//头插法(先来的节点有所指向,指向head->next)
        head->next = p;      //头部节点指向新来的节点
        p = q;               //节点向后移位
    }
    return head;
}
//两两交换eg 5->4->3->2->1->NULL  4->5->2->3->1->NULL
Node *changeTwoLink(Node*head)
{
    Node *cur = head;
    Node *m=cur->next;

    while (((cur!=NULL)&&(cur->next!=NULL))&&(m->next!=NULL))
     {
         Node* node1 = cur->next;  //指针移动
         Node* node2 = node1->next;
         Node* rear = node2->next;

         cur->next = node2;       //指针交换
         node2->next = node1;
         node1->next = rear;
         cur = node1;
         m=cur->next;
        }
    return head;
}
//查找指定元素的地址
char * findLink(Node*head,int data)
{
    Node *p=head->next;
    while (p)
    {
        if(p->data==data)
        {
            break;
        }
        p=p->next;
    }
    return p;
}
//删除指定元素
void deleteLink(Node*head,int n)
{
    Node*p=head->next;
    int m=1;
    while (m!=n-1) {
        p=p->next;
        m++;
    }
    Node *q=p->next;
    p->next=q->next;
    free(q);
}
//把所有的链表元素输出
void printLink(Node*head)
{
    Node *p=head->next;
    while (p) {
        printf("%d\n",p->data);
        p=p->next;
    }
}
//释放链表
void releaseLink(Node *head)
{
    Node * p;
    while(head)
    {
        p = head->next;
        free(head);
        head = p;
    }
    printf("the link have been released!\n");
}

int main()
{
    Node *head = createLink();
    head = addEndLink(head);
    printLink(head);
    int len =lenLink(head);

    printf("the length of link is %d\n",len);
    sortPopAdressLink(head,len);
    printf("after pop sort\n");
    printLink(head);
    addLink(head,2,10);
    printf("====================\n");
    printLink(head);
    printf("=========inverse========\n");
    inverseLink(head);
    printLink(head);
    printf("=========change========\n");
    changeTwoLink(head);
    printLink(head);
    printf("adress = %p\n",findLink(head,78));
    deleteLink(head,3);
    printf("===============after delete======\n");
    printLink(head);
    releaseLink(head);
    return 0;
}

链表操作的几个小结

1.采用头插法构建链表记住:让新来的节点有所指向,头节点下一个节点指向新来的节点。即cur->next = head->next;head->next = cur;
2.链表反转的核心思想:先把头节点打断,让头节点指向NULL,然后用头插法的原则将元素一个个往头部插入,如此一来第一个节点就到最后的节点,即让链表反转。
3.mallco从堆上申请空间后一定记住释放,遵守先申请后释放,后申请先释放的原则,类似栈原理。

你可能感兴趣的:(C语言学习篇)