链表常用函数实现

单向链表常用函数实现

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

#define Elemtype int

//所有列表均含头结点,单向链表

//结点定义
struct node{
    Elemtype val;
    struct node* next;
};

//实现的函数清单
struct node* Create_List(); //创建一个列表
struct node* Create_Node(Elemtype val);//创建一个结点
struct node* Clear_List(struct node* head);//清空列表
void Destory_List(struct node** head); //销毁列表
bool List_IsEmpty(struct node* head); //判断链表是否为空
int List_Length(struct node* head); //计算链表的长度
bool Get_List_Element(struct node* head,int i,Elemtype* e); //查找第i个值
void Print_List(struct node* head);//打印链表
bool List_Insert(struct node* head, int i,struct node* new_node); //在第i个位置插入结点
void List_Append(struct node*head,struct node*new_node); //在链表的最后添加结点
void List_Insert_in_First(struct node *head,struct node* new_node);//在首位添加结点
bool delete_List(struct node* head,int i); //删除第i个元素


struct node* Create_List() //创建一个列表
{
    int elemt_num;
    printf("Enter the number of elemt: ");
    scanf("%d",&elemt_num);
    struct node*head = (struct node*)malloc(sizeof(struct node)); //创建一个头结点
    struct node* temp = head;
    head->next = NULL;
    for(int i = 0; i < elemt_num; i++){
        Elemtype elemt;
        printf("Node #%d val:",i+1);
        scanf("%d", &elemt);
        struct node* p = Create_Node(elemt);
        temp->next = p;
        p->next = NULL;
        temp = temp->next;
    }
    return head;
}

struct node* Create_Node(Elemtype val)//创建一个结点
{
    struct node* temp = (struct node*)malloc(sizeof(struct node));
    temp->next = NULL;
    temp->val = val;
    return temp;
}

struct node* Clear_List(struct node* head) //清空列表
{
    struct node *temp = NULL; //初始化清空目标
    while(head->next != NULL){
        temp = head->next;
        head->next = temp->next; 
        //把要清空的结点单独扔出来
        //防止清空该结点以后指向结点后面的指针消失
        free(temp);   //虽然平常学习应该可能不会内存泄漏,但一定要规范,万一呢=。=
        temp = NULL;
    }
    return head;
}

void Destory_List(struct node** head) //销毁列表
{
    Clear_List(*head); 
    free(*head);  //所谓销毁就是清空后把头结点释放掉
    *head = NULL; //关键头指针要置空不要乱指
    /*注意:指针被free后依然指向原内存地址,只是该内存已变成垃圾,要及时置零,避免野指针*/
    return;
}

bool List_IsEmpty(struct node* head) //判断链表是否为空
{
    if(head->next == NULL)
        return true;
    return false;
}

int List_Length(struct node* head) //计算链表的长度
{
    struct node* temp = head->next; //不要改变头指针的指向
    int num = 0;
    while(temp){
        ++num;
        temp = temp->next;
    }
    return num;
}

bool Get_List_Element(struct node* head,int i,Elemtype *e) //查找第i个值
{
    struct node* temp = head->next;
    if(List_Length(head) >= i && i > 0){
        for(int j = 1;j <= i;j++)
            temp = temp->next;
        *e = temp->val;
        return true;
    }
    else
        printf("The number of i is invalid,may be more than length of Linked List.\n");

    return false;
}

void Print_List(struct node* head)//打印链表
{
    struct node*temp = head->next;
    int i = 1;
    while(temp){
        printf("Node#%d val: %d\n",i,temp->val);  //默认elemtype为int型
        i++;
        temp = temp->next;
    }
    return;
}

bool List_Insert(struct node* head, int i,struct node* new_node) //在第i个位置插入结点
{
    struct node* temp = head->next;
    if(List_Length(head) >= i && i > 0){
        int j = 1;
        while(j != i-1){          //寻找第i个值,查询链表的val时间复杂度是O(n)
            temp = temp->next;
                j++;
        }
        new_node->next = temp->next;
        temp->next = new_node;           //两步不能调换
        return true;
    }
    else
        printf("The number of i is invalid,may be more than length of Linked List.\n");
    return false;
}

void List_Append(struct node*head,struct node* new_node) //在链表的最后添加结点
{
    struct node* temp = head;
    while(temp->next)          //寻找最后一个结点
        temp = temp->next;
    temp->next = new_node;
    new_node->next = NULL;
    return;
}

void List_Insert_in_First(struct node *head,struct node* new_node)//在首位添加结点
{
    /*用的不多,常用于栈结构的链表实现*/
    new_node->next = head->next;
    head->next = new_node;
    return;
}

bool delete_List(struct node* head,int i) //删除第i个元素
{
    struct node* temp = head->next,*prev_temp = head; //删除结点需要两个指针,prev_temp表示temp前一个结点地址
    if(List_Length(head) >= i && i > 0){            //因为删除要知道前一个结点的next指针
        int j = 1;
        while(j != i){
            temp = temp->next;
            prev_temp = prev_temp->next;
                j++;
        }
        prev_temp->next = temp->next;
        free(temp);
        temp = NULL;

        return true;
    }
    else
        return false;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值