C语言 翁凯老师 数据结构 链表学习(2)

遍历list,将链表里的数据输出

#include<stdio.h>
#include<stdlib.h>
#include"node.h"
/* typedef struct _node
{
    int value;
    struct  _node *next;
} Node; */
typedef struct _list
{
    Node* head;
    Node* tail;//永远指向最后一个节点
}List;
void * add(List *plist,int number);// 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用
void print(List *pList);/* 将链表遍历输出的子函数 */
int main()
{
    List list;
    list.head = list.tail = NULL;
    int number;
    do{
        scanf("%d",&number);
        if(number != 1){
            add(&list,number);
            // head = add(head,number);
        }
    }while (number != -1);
    printf(&list);
    return 0;
}

void * add(List *plist,int number)
{
    //add to linked-list
    Node *p = (Node*)malloc(sizeof(Node));
    p->value = number;
    p->next = NULL;
    //find the last
    Node *last = plist->tail;
    if(last){
        /* while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
            last = last->next;
        }
        // attach */
        last->next = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }else{
        plist->head = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }
    // return head;
}
/*这就是将链表遍历输出的子函数*/
void print(List *pList)
{
	Node *p;
	for(p = pList->head; p ; p = p->next)//结束的条件是p不存在 //这就是链表的遍历,将链表里存储的东西从头输出到尾。 
	{
		printf("%d\t",p->value);
	}
    printf("\n");
} 

对链表内部数据进行查找:输入一个数据,查找链表内有无此数据

#include<stdio.h>
#include<stdlib.h>
#include"node.h"
/* typedef struct _node
{
    int value;
    struct  _node *next;
} Node; */
typedef struct _list
{
    Node* head;
    Node* tail;//永远指向最后一个节点
}List;
void * add(List *plist,int number);// 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用
void print(List *pList);/* 将链表遍历输出的子函数 */
int main()
{
    List list;
    list.head = list.tail = NULL;
    int number;
    do{
        scanf("%d",&number);
        if(number != 1){
            add(&list,number);
            // head = add(head,number);
        }
    }while (number != -1);
    
    printf(&list);

    //链表的查找
    scanf("%d",&number);
    Node *p;
    int isFound = 0;
    for(p = list.head; p ;p->next){
        if(p->value == number){
            printf("find it\n");
            isFound = 1;
            break;
        }
    }
    if( !isFound ){
        printf("can't find it");
    }

    return 0;
}

void * add(List *plist,int number)
{
    //add to linked-list
    Node *p = (Node*)malloc(sizeof(Node));
    p->value = number;
    p->next = NULL;
    //find the last
    Node *last = plist->tail;
    if(last){
        /* while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
            last = last->next;
        }
        // attach */
        last->next = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }else{
        plist->head = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }
    // return head;
}
/*这就是将链表遍历输出的子函数*/
void print(List *pList)
{
	Node *p;
	for(p = pList->head; p ; p = p->next)//结束的条件是p不存在 //这就是链表的遍历,将链表里存储的东西从头输出到尾。 
	{
		printf("%d\t",p->value);
	}
    printf("\n");
} 

也可以将scanf放在主函数外,封装为另外一个搜索函数

8、删除链表中所储存的一个数。(注意这个程序所以只会删除搜索到的第一个数)

#include<stdio.h>
#include<stdlib.h>
#include"node.h"
/* typedef struct _node
{
    int value;
    struct  _node *next;
} Node; */
typedef struct _list
{
    Node* head;
    Node* tail;//永远指向最后一个节点
}List;
void * add(List *plist,int number);// 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用
void print(List *pList);/* 将链表遍历输出的子函数 */
int main()
{
    List list;
    list.head = list.tail = NULL;
    int number;
    do{
        scanf("%d",&number);
        if(number != 1){
            add(&list,number);
            // head = add(head,number);
        }
    }while (number != -1);

    printf(&list);

    //链表的查找
    scanf("%d",&number);
    Node *p;
    int isFound = 0;
    for(p = list.head; p ;p->next){
        if(p->value == number){
            printf("find it\n");
            isFound = 1;
            break;
        }
    }
    if( !isFound ){
        printf("can't find it\n");
    }

    Node *q;
    for(q = NULL,p = list.head; p ;q=p,p->next){
        if(p->value == number){
            if( q )
            {
                q->next = p->next;
            }else{
                list.head = p->next;
            }
            free(p);
            break;
        }
    }

    return 0;
}

void * add(List *plist,int number)
{
    //add to linked-list
    Node *p = (Node*)malloc(sizeof(Node));
    p->value = number;
    p->next = NULL;
    //find the last
    Node *last = plist->tail;
    if(last){
        /* while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
            last = last->next;
        }
        // attach */
        last->next = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }else{
        plist->head = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }
    // return head;
}
/*这就是将链表遍历输出的子函数*/
void print(List *pList)
{
	Node *p;
	for(p = pList->head; p ; p = p->next)//结束的条件是p不存在 //这就是链表的遍历,将链表里存储的东西从头输出到尾。 
	{
		printf("%d\t",p->value);
	}
    printf("\n");
} 

若将其封装为查找和删除函数:

#include<stdio.h>
#include<stdlib.h>
#include"node.h"
/* typedef struct _node
{
    int value;
    struct  _node *next;
} Node; */
typedef struct _list
{
    Node* head;
    Node* tail;//永远指向最后一个节点
}List;
void * add(List *plist,int number);// 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用
void print(List *pList);/* 将链表遍历输出的子函数 */
int main()
{
    List list;
    list.head = list.tail = NULL;
    int number;
    do{
        scanf("%d",&number);
        if(number != 1){
            add(&list,number);
            // head = add(head,number);
        }
    }while (number != -1);

    printf(&list);

    found(&list);//链表的查找

    delete(&list);//链表的删除
    return 0;
}

void * add(List *plist,int number)
{
    //add to linked-list
    Node *p = (Node*)malloc(sizeof(Node));
    p->value = number;
    p->next = NULL;
    //find the last
    Node *last = plist->tail;
    if(last){
        /* while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
            last = last->next;
        }
        // attach */
        last->next = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }else{
        plist->head = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }
    // return head;
}
/*这就是将链表遍历输出的子函数*/
void print(List *pList)
{
	Node *p;
	for(p = pList->head; p ; p = p->next)//结束的条件是p不存在 //这就是链表的遍历,将链表里存储的东西从头输出到尾。 
	{
		printf("%d\t",p->value);
	}
    printf("\n");
} 

void found(List *flist){
    int number = 0;
    scanf("%d",&number);
    Node *p;
    int isFound = 0;
    for(p = flist->head; p ;p->next){
        if(p->value == number){
            printf("find it\n");
            isFound = 1;
            break;
        }
    }
    if( !isFound ){
        printf("can't find it\n");
    }

}

void delete(List *flist)
{
    int number;
    scanf("%d",&number);
    Node *p,*q;
    for(q = NULL,p = flist->head;p;q=p,p=p->next){
        if(p->value == number){
            if(q){//保证q是可操作的而不是NULL,如果没有这个if,当所要删除的数是在第一个位置时,将会出现错误。 
                q->next = p->next;
            }else{
                flist->head = p->next;
            }
            free(p);
            break;
        }
    }
}

缺点是无法在删除之后输出链表,需要重新输出一下

链表的释放和清除

开辟了一片存储链表的空间,在最后要把这片空间给释放掉

#include<stdio.h>
#include<stdlib.h>
#include"node.h"
/* typedef struct _node
{
    int value;
    struct  _node *next;
} Node; */
typedef struct _list
{
    Node* head;
    Node* tail;//永远指向最后一个节点
}List;
void * add(List *plist,int number);// 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用
void print(List *pList);/* 将链表遍历输出的子函数 */
void found(List *flist);/* 链表元素的查找子函数 */
void delete(List *flist);/* 链表元素的删除子函数 */
void Free(List *flist);
int main()
{
    List list;
    list.head = list.tail = NULL;
    int number;
    do{
        scanf("%d",&number);
        if(number != 1){
            add(&list,number);
            // head = add(head,number);
        }
    }while (number != -1);

    print(&list);//将链表遍历输出

    found(&list);//链表的查找

    delete(&list);//链表元素的删除

    Free(&list);

    return 0;
}

void * add(List *plist,int number)
{
    //add to linked-list
    Node *p = (Node*)malloc(sizeof(Node));
    p->value = number;
    p->next = NULL;
    //find the last
    Node *last = plist->tail;
    if(last){
        /* while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
            last = last->next;
        }
        // attach */
        last->next = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }else{
        plist->head = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }
    // return head;
}
/*这就是将链表遍历输出的子函数*/
void print(List *pList)
{
	Node *p;
	for(p = pList->head; p ; p = p->next)//结束的条件是p不存在 //这就是链表的遍历,将链表里存储的东西从头输出到尾。 
	{
		printf("%d\t",p->value);
	}
    printf("\n");
} 

void found(List *flist){
    int number = 0;
    scanf("%d",&number);
    Node *p;
    int isFound = 0;
    for(p = flist->head; p ;p->next){
        if(p->value == number){
            printf("find it\n");
            isFound = 1;
            break;
        }
    }
    if( !isFound ){
        printf("can't find it\n");
    }

}

void delete(List *flist)
{
    int number;
    scanf("%d",&number);
    Node *p,*q;
    for(q = NULL,p = flist->head;p;q=p,p=p->next){
        if(p->value == number){
            if(q){//保证q是可操作的而不是NULL,如果没有这个if,当所要删除的数是在第一个位置时,将会出现错误。 
                q->next = p->next;
            }else{
                flist->head = p->next;
            }
            free(p);
            break;
        }
    }
}

void Free(List *flist){
    Node *p,*q;
    for(p = flist->head; p;p = q){
        q = p->next;
        free(p);
    }
}

即上述的Free函数,也可以直接卸载主函数的最后部分。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

某石油中专在读坐牢2021级本科生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值