头插法创建一个单链表,操作元素为结构体

一.要求
1.头插法创建一个单链表,其中储存学生的姓名,学号,成绩信息,输出链表内容,预期结果为:
Xiao 1 92
Song 2 93
Zhao 3 96
Li 4 78
Qian 5 98
Huang 6 93
2.在第一个节点前插入一个学生的信息,姓名:Xin,学号:10,成绩:98,并输出所有学生的姓名,预期结果为:
Xin
Xiao
Song
Zhao
Li
Qian
Huang
3.删除名字为Song的学生的信息,并输出改变后的所有学生的成绩,预期结果为:
98
92
96
78
98
93
二.代码



#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define ERROR 0
#define OVERFLOW -1
#define OK 1
using namespace std;

typedef int Status;

typedef struct ElemType
{
        char name;
    int num;
    int score;
}ElemType;

typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;


//头插法创建单链表
Status CreateListHead_L(LinkList &L,int n){
    L=(LinkList)malloc(sizeof(LNode));
    if(!L){
        return OVERFLOW;
    }
    L->next=NULL;//建立一个带头结点的单链表 
    LinkList p;
    for(int i=0;i<n;i++){
        p=(LinkList)malloc(sizeof(LNode));
        printf("请输入学生信息:") ;
        scanf(&p->data);
        p->next=L->next;
        L->next=p;
    }
    return OK;
}

//获得链表第i个元素
//算法思路:
/*
    1. 声明一个节点p指向第一个节点,用于遍历链表
    2. 定义一个计时器j从1开始,j<i时,遍历链表,j++
    3. 查找成功:p!=NULL&&j=i
    4. 查找失败:p==NULL||j>i
 */
Status GetElem_L(LinkList L,int i,ElemType &e){
    LinkList p; 
    int j=1;    //j为计数器
    p=L->next;   //p指向链表第1个节点
    while (p&&j<i) {//顺时针向后查找,直到p指向第i个元素或p为空 
        p=p->next;
        j++;
    }
    if(!p||j>i){
        return ERROR;//第一个元素不存在 
    }
    e=p->data;//取第i个元素 
    return OK;
}

//向单链表中插入一个元素
Status InsertList_L(LinkList &L,ElemType e,int i){
    LinkList p;
    p=L;
    int j=0;
    while (p&&j<i-1) {
        p=p->next;
        j++;
    }
    if(!p||j>i-1){
        printf("插入位置有错\n");
        return ERROR;//插入位置有错
    }
    LinkList s;
    s=(LinkList)malloc(sizeof(LNode));
    s->data=e;
    s->next=p->next;
    p->next=s;
    return OK;
}

//删除元素
Status DeleteList_L(LinkList &L,int i,ElemType &e){
    LinkList p;
    p=L;
    int j=0;
    while (p->next&&j<i-1) {
        p=p->next;
        j++;
    }
    if(!(p->next)||j>i-1){
        printf("出错了");
        return ERROR;
    }
    LinkList q;
    q=p->next;
    e=q->data;
    p->next=q->next;
    free(q);
    return OK;
}


//打印链表元素
Status PrintList(LinkList L){
    LinkList p;
    p=L->next;
    while (p) {
        printf("%c",p->data.name);
        printf("%d",p->data.num);
        printf("%d",p->data.score);
        p=p->next;
    }
    return OK;
}

int main(){
    int i,j;
    LinkList L;
    L=CreateListHead_L(&L,6);
    printf("学生信息为:");
    PrintList(L);
    ElemType e;
    e.name="Xin";
    e.num=10;
    e.score=98;
    L=InsertList_L(L,e,1);
    for(int i=0;i<7;i++)
        {printf("在第一个节点前插入一个元素后学生的姓名为%c:",L->data[i].name);
        printf("\n");
        }
    L=DeleteList_L(L,3,e)
    for(int i=0;i<7;i++)
        {printf("删除第三个元素后学生的成绩为%d:",L->data[i].name);
        printf("\n");
        }
    return 0;
}

三.报错太多,求解(跪)

C语言中没有iostream,iostream是C++的
C语言中也没有string类型,string也是C++的
C语言中也没有引用,所以函数参数中的&也是不对的
修改后运行结果:

img

代码修改如下:



#include <stdio.h>
//#include <iostream>
#include <stdlib.h>
#include <string.h>
#define ERROR 0
#define OVERFLOW -1
#define OK 1
using namespace std;

typedef int Status;

typedef struct _ElemType
{
    char name[20];//string name;
    int num;
    int score;
}ElemType;

typedef struct _LNode {
    ElemType data;
    struct _LNode* next;
}LNode, * LinkList;


//头插法创建单链表
Status CreateListHead_L(LinkList* L, int n) {
    *L = (LinkList)malloc(sizeof(LNode));
    if (!(*L)) {
        return OVERFLOW;
    }
    (*L)->next = NULL;//建立一个带头结点的单链表 
    LinkList p;
    for (int i = 0; i < n; i++) {
        p = (LinkList)malloc(sizeof(LNode));
        printf("请输入学生信息:");
        scanf("%s %d %d" ,p->data.name,&p->data.num,&p->data.score);
        p->next = ( * L)->next;
        (*L)->next = p;
    }
    return OK;
}

//获得链表第i个元素
//算法思路:
/*
    1. 声明一个节点p指向第一个节点,用于遍历链表
    2. 定义一个计时器j从1开始,j<i时,遍历链表,j++
    3. 查找成功:p!=NULL&&j=i
    4. 查找失败:p==NULL||j>i
 */
Status GetElem_L(LinkList L, int i, ElemType* e) {
    LinkList p;
    int j = 1;    //j为计数器
    p = L->next;   //p指向链表第1个节点
    while (p && j < i) {//顺时针向后查找,直到p指向第i个元素或p为空 
        p = p->next;
        j++;
    }
    if (!p || j > i) {
        return ERROR;//第一个元素不存在 
    }
    *e = p->data;//取第i个元素 
    return OK;
}

//向单链表中插入一个元素
Status InsertList_L(LinkList* L, ElemType e, int i) {
    LinkList p;
    p = *L;
    int j = 0;
    while (p && j < i - 1) {
        p = p->next;
        j++;
    }
    if (!p || j > i - 1) {
        printf("插入位置有错\n");
        return ERROR;//插入位置有错
    }
    LinkList s;
    s = (LinkList)malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return OK;
}

//删除元素
Status DeleteList_L(LinkList* L, int i, ElemType* e) {
    LinkList p;
    p = *L;
    int j = 0;
    while (p->next && j < i - 1) {
        p = p->next;
        j++;
    }
    if (!(p->next) || j > i - 1) {
        printf("出错了");
        return ERROR;
    }
    LinkList q;
    q = p->next;
    *e = q->data;
    p->next = q->next;
    free(q);
    return OK;
}


//打印链表元素
Status PrintList(LinkList L) {
    LinkList p;
    p = L->next;
    while (p) {
        printf("%s ", p->data.name);
        printf("%d ", p->data.num);
        printf("%d\n", p->data.score);
        p = p->next;
    }
    return OK;
}


//打印链表元素--只显示名字
Status PrintList_name(LinkList L) {
    LinkList p;
    p = L->next;
    while (p) {
        printf("%s\n", p->data.name);
        p = p->next;
    }
    return OK;
}

//打印链表元素--只显示成绩
Status PrintList_score(LinkList L) {
    LinkList p;
    p = L->next;
    while (p) {
        printf("%d\n", p->data.score);
        p = p->next;
    }
    return OK;
}

int main() {
    int i, j;
    LinkList L;
    CreateListHead_L(&L, 6);
    printf("学生信息为:\n");
    PrintList(L);
    ElemType e;
    strcpy(e.name ,"Xin");
    e.num = 10;
    e.score = 98;
    InsertList_L(&L, e, 1);
    printf("在第一个节点前插入一个元素后学生的姓名为:\n");
    PrintList_name(L);



    DeleteList_L(&L, 3, &e);
    printf("删除第三个元素后学生的成绩为:\n");
    PrintList_score(L);

    return 0;
}