数据结构之链表

线性表的链式存储

单向链表

链表结点的数据类型

typedef int DataType;
typedet struct node
{
    //保存结点数据
    DataType data;
    //保存下一个结点的首地址
    struct node *next;
}LinkNode;

常用操作
1.创建空链表,只有头结点,且其指针域为NULL
LinkNode *create_empty_linklist()
{
    1.为头结点在堆区分配空间,用指针变量head保存申请空间的首地址
    2.head->next = NULL;
    3.head 返回
}

2.头插法,在头结点后插入新结点
int insert_head_linklist(LinkNode *head,DataType data)
{
    1.为新结点在堆区分配空间,用temp保存申请空间的首地址
    2.temp->data = data;
    
    temp->next = head->next;
    head->next = temp;

    return 0;
}

3.尾插法,在尾结点后插入新结点
int insert_tail_linklist(LinkNode *head,DataType data)
{
    1.为新结点在堆区分配空间,用temp保存申请空间的首地址
    2.temp->data = data;

    3.找到尾结点,
    p = head;
    while(p->next) 
    {
        p = p->next;
    }
    
    4,尾结点后插入
    temp->next = p->next;
    p->next = temp;

    return 0;
}

4.有序插入,找到插入位置前一结点
int insert_order_linklist(LinkNode *head,DataType data)
{
    LinkNode *p = head;
#if 0
    while(p->next)
    {
        if(p->next->data > data)
        {
            break;
        }
        p = p->next;
    }
#endif
    
    while(p->next && p->next->data < data)
    {
        p = p->next;
    }
}

5.输出链表所有结点的数据
int print_linklist(LinkNode *head)
{
    头结点未保存有效数据,
    所有结点都遍历到
}

6.删除指定元素
int delete_assign_node(LinkNode *head,DataType data)
{
    1.找到删除结点的前一结点
    2.保存删除结点的首地址
    3.让链表重新连接
    4.释放删除结点的空间
}

7.清空整个链表
int cleanup_linklist(LinkNode *head)
{
    遍历整个链表,每次删除头结点
}


code-1:head.h

#ifndef __HEAD__H
#define __HEAD__H

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

typedef int DataType;
typedef struct node
{
    DataType data;//保存结点数据
    struct node *next;//保存下一个结点的首地址
}LinkNode;

extern LinkNode *create_empty_linklist();
extern int insert_tail_linklist(LinkNode *head,DataType data);
extern int print_linklist(LinkNode *head);
extern int insert_head_linklist(LinkNode *head,DataType data);
extern int insert_order_linklist(LinkNode *head,DataType data);
extern int inverted_linklist(LinkNode *head);
extern int order_linklist(LinkNode *head);
extern int delete_linknode(LinkNode *head,int pos);
extern int is_empty_list(LinkNode *head);
extern int delete_linklist(LinkNode *head);
extern int delete_num_node(LinkNode *head,int data);
extern int delete_num_node_byhand(LinkNode *head);

#endif

code-2:Mylinklist.c

#include "head.h"

//创建一个新的空链表
LinkNode *create_empty_linklist()/*{{{*/
{
    LinkNode *head = NULL;//局部变量,放在栈中,用完及时释放空间归还内存
    
    head = (LinkNode *)malloc(sizeof(LinkNode));//在堆区分配内存
    head->next = NULL;//堆区分配对空链表,规定头指针为head,
                      //由于没有分配新的结点,其指针域为空NULL

    return head;//返回头指针 

}/*}}}*/

//链表判空
int is_empty_list(LinkNode *head)/*{{{*/
{
    return head->next == NULL;
}/*}}}*/

//利用头插法在头指针前面插入一个新的结点
//*{{{*/
//在堆区分配一个新的空间
int insert_head_linklist(LinkNode *head,DataType data)
{
    LinkNode *temp = NULL;
    
    temp = (LinkNode *)malloc(sizeof(LinkNode ));
    memset(temp,0,sizeof(LinkNode));//将新申请的空间手动清零
    temp->data = data;
    
    temp->next = head->next;
    head->next = temp;

    return 0;
}/*}}}*/

//利用尾插法在尾指针前面插入一个新的结点
//*{{{*/ /先分配一个新的结点(在堆区)
//在交换指针域
int insert_tail_linklist(LinkNode *head,DataType data)
{
    LinkNode *temp = NULL;
    LinkNode *p = NULL;
    //在堆区分配一个新对空间,用temp保存申请空间对首地址
    temp = (LinkNode *)malloc(sizeof(LinkNode ));
    memset(temp,0,sizeof(LinkNode));//将新申请的空间手动清零
    temp->data = data;//数据保存在分配对新空间内
    //temp->next = NULL;可以直接将新分配的尾结点直接赋空

    //下一步就是找到尾结点
    p = head;
    while(p->next)
    {
        p = p->next;//当p-》next指向的还不是空,即p不是尾结点时,
                    //p继续指向下一个结点,直到指向尾结点
    }

    //交换指针域,即在上一个尾结点后插入了一个新元素
    temp->next = p->next;
    p->next = temp;

    return 0;
}/*}}}*/

//有序插入法,
int insert_order_linklist(LinkNode *head,DataType data)/*{{{*/
{
    LinkNode *p = head;
    LinkNode *temp = NULL;

    temp = (LinkNode*)malloc(sizeof(LinkNode));
    temp->data = data;
    
    //遍历整个链表,找到插入位置前一结点
    while(p->next)
    {
        if(p->next->data > data)//要插入的位置对数据比欲插入数据大则在
                                //该位置之前结点的后面插入    
        {
            break;
        }
        p = p->next;
    }
    
    while(p->next && p->next->data > data)
    {
        temp->next = p->next;
        p->next = temp;
    }

    
}/*}}}*/

//删除整个链表
int delete_linklist(LinkNode *head)/*{{{*/
{

}
/*}}}*/

//打印链表
int print_linklist(LinkNode *head)/*{{{*/
{
    LinkNode *lklst = NULL;
    lklst = head->next;

    //while(lklst != NULL)
    while(lklst)
    {
        printf("%-5d",lklst->data);

        lklst = lklst->next;

    }

    putchar('\n');

    return 0;

}/*}}}*/

//链表逆置
int inverted_linklist(LinkNode *head)/*{{{*/
{
    LinkNode *temp = head;
    LinkNode *head_p = head;
    LinkNode *p1 = NULL;
    LinkNode *p2 = NULL;
    LinkNode *p3 = head;
    int i = 0;
    
    //当链表为空链表时,无需逆置
    if(is_empty_list(head))
    {
        return -1;
    }
    
    //当链表只有一个结点时,无需逆置
    if(head->next->next == NULL)
    {
        return -1;
    }

    while(temp->next)
    {
        p1 = head;
        while(p1->next->next)
        {
            p1 = p1->next;
        }
        p2 = p1->next;
        p1->next = NULL;

        p2->next = temp->next;
        temp->next = p2;
        temp = temp->next;
    } 
}
/*}}}*/

//链表按序排列
int order_linklist(LinkNode *head)/*{{{*/
{
    LinkNode *max = NULL;
    LinkNode *min = NULL;
    int temp;
    for(max = head->next;max != NULL;max = max->next)
    {
        for(min = max->next;min != NULL;min = min->next)
        {
            if(max->data < min->data)
            {
               // max->data ^= min->data;
               // min->data ^= max->data;
               // max->data ^= min->data;
               temp = max->data;
               max->data = min->data;
               min->data = temp;

            }
         //   printf("min = %p,min->next = %p\n",min,min->next);
        }
    }
}

/*}}}*/

//删除指定结点
int delete_linknode(LinkNode *head,int pos)/*{{{*/
{   
    //int pos = 0;
    LinkNode *p = head;
    LinkNode *temp = NULL;
    int i = 0;
#if 0
    printf("请输入要删除的结点数:");
    getchar();

    scanf("%d",&pos);
    getchar();
    printf("%d\n",pos);
 
#endif
    while(i != pos -1)
    {
        p = p->next;
        i++;
    }
    
    temp = p->next;
    p->next = temp->next;

}/*}}}*/

//在函数参数中指定删除一个数,然后释放结点
int delete_num_node(LinkNode *head,int data)/*{{{*/
{
    LinkNode *temp = NULL;
    LinkNode *p = head;

    while(p->next && p->next->data != data)
    {
        p = p->next;
    }

    if(p->next == NULL)
    {
        return -1;
    }

    temp = p->next;
    p->next = p->next->next;
    free(temp);

}/*}}}*/

//调用删除函数后手动输入需要删除的数据结点
int delete_num_node_byhand(LinkNode *head)/*{{{*/
{
    int data = 0;
    LinkNode *temp = NULL;
    LinkNode *p = head;

    print_linklist(head);
    printf("请输入要删除的结点数:");
    scanf("%d",&data);
    printf("data = %d\n",data);

    while(p->next && p->next->data != data)
    {
        p = p->next;
    }

    if(p->next == NULL)
    {
        return -1;
    }

    temp = p->next;
    p->next = p->next->next;
    free(temp);

}
/*}}}*/

code-3:main.c

#include "head.h"

int main()
{
   long long i = 0;
   LinkNode *head = NULL;

   head = create_empty_linklist();

   insert_tail_linklist(head,34);
   insert_tail_linklist(head,45);
   insert_tail_linklist(head,56);
   insert_tail_linklist(head,67);
   print_linklist(head);

   insert_order_linklist(head,44);
   insert_order_linklist(head,49);
   print_linklist(head);

   inverted_linklist(head);
   print_linklist(head);

   //insert_head_linklist(head,1);
   insert_head_linklist(head,3);
   insert_head_linklist(head,1);
   print_linklist(head);
   
   //getchar();
   //printf("下面将链表按大小顺序排序\n");
   print_linklist(head);
   order_linklist(head);
   print_linklist(head);

   //getchar();
   //delete_linknode(head,3);
   //print_linklist(head);
   delete_linknode(head,3);
   print_linklist(head);
   delete_num_node(head,3);
   print_linklist(head);

   delete_num_node_byhand(head);
   print_linklist(head);
   //delete_linknode(head);
   //print_linklist(head);

   return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值