c实现数据结构中单向链表创建,插入,删除,查找,销毁

本文介绍了如何使用C语言创建、插入、删除、查找和销毁单向链表。通过实例详细讲解了每个操作的步骤和关键代码,帮助读者深入理解链表数据结构。

#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100
#define ElementType int
typedef struct node{
    ElementType data;
    struct node *link;
}LNode,*LinkList;
//求链表长度
int LENGTH(LinkList list);
//创建链表
LinkList CREATE(int n);
//输出链表
void print(LinkList list);
//插入item元素
void INSERTLINK1(ElementType item,LinkList list);
//指定位置插入元素item
void INSERTLINK3(LinkList list,int i,ElementType item);
//销毁线性链表
LinkList DESTORYLINKLIST(LinkList list);
//销毁线性链表中相同元素
LinkList DELETESAMEELEMENT(LinkList list);
//移动最小值结点到链表表头
LinkList removemin(LinkList list);
//移动最大值结点到链表表头
LinkList removemax(LinkList list);
int main(){
    LinkList list;
    ElementType item;
    printf("create linklist\n");
    list = CREATE(10);
    int length = LENGTH(list);
    printf("链表长度为%d\n",length);
    print(list);
//    printf("请输入想插入到链表头的数据");
//    scanf("%d",&item);
//    print(INSERTLINK1(item,list));
//    printf("在第2个结点后插入数据\n");
//    print(INSERTLINK3(list,2,item));
//    printf("destory list\n");
//    print(DESTORYLINKLIST(list));
//    printf("销毁线性链表中相同的元素\n");
//    print(DELETESAMEELEMENT(list));
//    printf("将值最小元素移到链表最前面\n");
//    print(removemin(list));
    printf("移动最大元素到链表结尾");
    print(removemax(list));
    
}
//创建线性链表
LinkList CREATE(int n){
    LinkList p,r,list=NULL;
    ElementType a;
    for(int i=1;i<=n;i++){
        printf("请输入第%d个数据",i);
        scanf("%d",&a);
        p = (LinkList) malloc(sizeof(LinkList));//申请一个新的链结点
        p->data = a;
        p->link=NULL;
        if (list == NULL) {
            list = p;
        }else{
            r->link = p;//将新结点链接在链表尾部
        }
        r=p;
    }
    
    
    return list;
}
//求线性链表长度,非递归算法
int LENGTH(LinkList list){
    LinkList p = list;
    int n=0;//链表长度置初值为0
    while(p!=NULL){
        p=p->link;
        n++;
    }
    return n;//返回链表长度
}
//打印链表中的数据
void print(LinkList list){
    LinkList p;
    p=list;
    printf("输出链表中的数据\n");
    while(p!=NULL){
        printf("%d\t",p->data);
        p=p->link;
    }
    printf("\n");
}
//第一个结点前插入数据项item的新结点
void INSERTLINK1(ElementType item,LinkList list){
    LinkList p;//list指向链表第一个链结点
    p=(LinkList)malloc(sizeof(LinkList));//s申请一个新结点
    p->data = item;//将item送新结点数据域
    p->link = list;//将list送新结点指针域
    list = p;//修改指针list指向
}
//在链结点q后面插入数据信息为item的链结点
void INSERTLINK2(LinkList list,LinkList q,ElementType item){
    LinkList p;
    p=(LinkList)malloc(sizeof(LinkList));//构造一个新结点
    p->data = item;//将item送新结点数据域
    if(list == NULL){//若原链表为空
        list = p;
        p->link = NULL;
    }else{//原链表不为空
        p->link = q->link;
        q->link = p;
    }
    
}
//在第i个结点后面插入一个数据信息为item的新结点
void INSERTLINK3(LinkList list,int i,ElementType item){
    LinkList p,q=list;
    for(int j=0;j<=i-1;j++){//存在第i个结点
        q=q->link;
        if(q == NULL){//不存在第i个结点
            break;
        }
    }
    p=(LinkList)malloc(sizeof(LinkList));//构造一个新结点
    p->data = item;//将item送入新结点数据域
    p->link = q->link;
    q->link = p;//将新结点插入到第i个结点之后
}
//从非空线性链表中删除q指的链结点,设q的直接前驱结点由r指出
void DELETELINK1(LinkList list,LinkList r,LinkList q){
    if(q == list){
        list = q->link;//删除链表的第一个链结点
    }else{
        r->link = q->link;//删除q指的链结点
       
    }
    free(q);//释放被删除的结点空间
}
//从非空链表中删除q指的链结点
void DELETELINK2(LinkList list,LinkList q){
    LinkList r;
    if(q == list){//当删除链表第一个结点
        list = list->link;
        free(q);//释放被删除结点的空间
    }else{
        //寻找q结点的直接前驱r
        r = list;
        while(r->link !=q && r->link!=NULL){//移向下一个链结点
            r = r->link;
        }
        if(r->link != NULL){
            r->link = q->link;
            free(q);
        }
    }
}
//查找list所指线性链表倒数第k个结点
LinkList SEARCHNODE(LinkList list ,int k){
    LinkList p,q;
    int i;
    if(list!=NULL && k>0){
        for(i=1;i<k;i++){//循环结束时,p指向链表的第k个结点
            p = p->link;
            if(p==NULL){
                printf("链表不存在倒数第k个结点");
            }
        }
    }
    q=list;
    while(p->link!=NULL){
        p=p->link;
        q=q->link;
    }//p指向链表最后那个结点,q指向倒数第k个结点
    return q;//给出链表倒数第k个结点(q指向的那个结点)的地址
}
//销毁线性链表
LinkList DESTORYLINKLIST(LinkList list){
    //list存放链表的首地址
    LinkList p=list;
    while(list!= NULL){
        list=list->link;//保存下一个链结点的位置
        free(p);//删除并释放p指的当前结点
        p=list;//下一链结点称为当前结点
    }
    return list;
}
//销毁线性链表中相同元素
LinkList DELETESAMEELEMENT(LinkList list){
    LinkList p,r,q;
    p=list;
    while(p!=NULL){
        r=p;
        q=p->link;
        while(q!=NULL){
            if(p->data == q->data){
                r->link = q->link;
                free(q);
                q=r->link;
            }else{
                r=q;
                q=r->link;
            }
        }
        p=p->link;
    }
    return list;
}
//移动最小值结点到链表表头
LinkList removemin(LinkList list){
    LinkList p,q,s,r;
    q=list;
    p=list->link;
    r=list;
    //找到值最小的那个结点
    while(p!=NULL){
        if(q->data > p->data){
            s=r;
            q=p;
        }
        r=p;
        p=p->link;
    }
    //若值最小结点不是链表最前面的那个点
    if(q!=list){
        s->link = q->link;
        q->link=list;
        list = q;
    }
    return list;
}
//移动最大值结点到链表表头
LinkList removemax(LinkList list){
    LinkList p,q,s,r;
    q=list;
    p=list->link;
    r=list;
    //寻找值最大的那个结点
    while(p!=NULL){
        if(q->data < p->data){
            s=r;
            q=p;
        }
        r=p;
        p=p->link;
    }
    //若值最大结点不是链表结尾的那个点
    if(q!=r){
        if(q!=list){
            //如果最大值不是链表头结点
            s->link = q->link;
        }else{
            //如果最大值是链表头结点
            list = q->link;
        }
        r->link=q;
        q->link=NULL;
    }
    return list;
}

 

1、已知一个链表中存储了若干名学生信息,每名学生信息包括:学号、英语成绩、数学成绩、计算机成绩。 现编写一个函数search(),要求对输入的无序学号进行排序,然后采用折半查找方法查找输入学生学号,并输出该学生各科成绩。 2、设计一个学生类(CStudent),它具有私有数据成员是:学号、姓名、数学、外语和计算机课程的成绩。要求能实现求三门课总成绩和平均成绩,并能设置和显示学生信息 (类声明和成员函数定义分离)。设计一个友元函数,按照成绩从高到低的顺序输出姓名、学号和成绩信息。 3、实现雇员管理,类Employee需存储雇员的姓名。这种信息对于所有雇员(包括Employee的派生类的雇员)是很普遍的。现在假设从雇员类Employee派生出了小时工类HourlyWorker、计件工类PieceWorker、老板类Boss和销售员类CommissionWorker。小时工每周工作40小时,超过40小时部分的报酬是平时的1.5倍;计件工是按生产的工作件数计算报酬的,每件的报酬是固定的,假设他只生成一种类型的工件,因而类PieceWorker的private数据成员是生产的工件数量和每件的报酬;老板每周有固定的薪水;销售员每周有小部分固定的基本工资加上其每周销售额的固定百分比。设计和规划该类体系,并分别产生每个基类及派生类对象,并显示该员工的工资。 4、约瑟夫生死者游戏 每30个旅客同乘一条船,因为严重超载,加上风高浪大,危险万分;因此船长告诉乘客,只有将全船一半的旅客投入海中,其余人才能幸免遇难。无奈,大家只得同意这种办法,并议定30个人围成一圈,由第一个人数起,依次报数,数到第9人,便把他投入大海中,然后再从他的下一个人数起,数到第9人,再将他扔进大海中,如此循环地进行,直到剩下15个乘客为止。问哪些位置是将是被扔下大海的位置。 5、求二叉树上结点的路径 要求在采用链式存储结构存储的二叉树上,以bt指向根结点,p指向任一给定的结点,编程实现求出从根节点到给定结点之间的路径。 6、图的操作 (1)写出将一个无向图的邻接矩阵转换成邻接表的算法 (2)设计一个算法,判断无向图G是否连通。若连通则返回1; 返回0。 7、内部排序算法的性能分析 要求:(1)对冒泡排序、直接排序、简单选择排序、快速排序、希尔排序、堆排序算法进行比较; (2)待排序表的表长不小于100,表中数据随机产生,至少用5组不同数据作比较,比较指标有:关键字参加比较次数和关键字的移动次数(关键字交换记为3次移动); (3)输出各种算法的排序结果和比较结果。 8.2、通讯录管理系统 编程实现通讯录管理系统,要求该系统能够完成通讯信息的建立、查询、插入删除等基本功能。程序运行后至少给出下面7个菜单项的选择并分别实现其功能: 0、 通讯录的建立 1、通讯录信息输出 2、 通讯者结点信息删除 3、通讯者结点信息的查询 4、 通讯者结点信息插入 5、通讯录信息更改 6、 退出通讯录管理系统 设计的任务要求,通讯录中每个学生的基本信息应包括姓名、地址、电话等基本信息,采用链表存储结构。(复习c语言结构体和链表知识)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值