入门结构体链表

入门结构体链表

Jun 5, 2013
C/C++

学完结构体发现这一章概括了这本C程序设计的多数知识点,遂做一个总结。

ps:代码在vs2012上测试,从简单的开始。

1.定义一个简单的结构体并输出

#include<stdio.h>
#include<stdlib.h>
struct stu{
	int num;
	char name[20];
	float score;
};
struct stu stu_1={01,"张三",90.5};
void main (){
	struct stu *p;
	p=&stu_1;
	printf("学生数据为:\n");
	printf("%ld%10s%10.2f\n",p->num,p->name,p->score);
	system("pause");
}

结构体的内容也可以在主函数中这样定义:

#include<stdio.h>
#include<stdlib.h>
struct stu{
	int num;
	char name[20];
	float score;
};
void main (){
	struct stu stu_1;
	struct stu *p;
	stu_1.num=01;
	strcpy(stu_1.name,"张三");
	stu_1.score=90.5;
	p=&stu_1;
	printf("学生数据为:\n");
	printf("%ld%10s%10.2f\n",p->num,p->name,p->score);
	system("pause");
}

发现这里的stu有点像面向对象里的类有木有。

2.上面的代码很容易理解的话,下一步尝试加入指向结构体元素的指针

#include <stdio.h>
#include <stdlib.h>
struct student {
	int num;
	char name[20];
	float score;
};
struct student stu[3]={{01,"张三",60},{02,"李四",59.5},{03,"王二",93.5}};
void main(){
	struct student *p;
	p=stu;
	for (p=stu;p<stu+3;p++){
		printf("%d%10s%10.2f\n",p->num,p->name,p->score);
	}
	system("pause");
}

3.创建一个简单的静态链表

能够创建一个加入了指针的结构体,理解指针的作用,就可以创建一个简单的链表了:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student {
	int num;
	char name[20];
	float score;
	struct student *next;
};
struct student stu_1={01,"张三",60},stu_2={02,"李四",59.5},stu_3={03,"王二",93.5};
void main(){
	struct student *head,*p;
	head=&stu_1;
	p=head;
	stu_1.next=&stu_2;
	stu_2.next=&stu_3;
	stu_3.next=NULL;
	do{
		printf("%d%10s%10.2f\n",p->num,p->name,p->score);
		p=p->next;
	}while(p!=NULL);
	system("pause");
	
}

4.创建一个动态链表

静态链表是之前都开辟好的空间,已经赋完值,明白malloc函数的用法后加上输入的功能就可以了:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct student {
    int num;
    float score;
    struct student *next;
};
struct student *head, *p, *p1;
int n = 0, i;
struct student *creat(){
    p1 = p = (struct student *)malloc(sizeof(struct student));
    scanf_s("%d%f", &p->num,&p->score);
    while(p->num!= NULL){
        n++;
        if(n == 1)head = p;
        else p1->next = p;
        p1 = p;
        p = (struct student *)malloc(sizeof(struct student));
        scanf_s("%d%f", &p->num,&p->score);
    }
    p1->next = NULL;
    return head;
}
void main (){
    head=creat();
    p = head;
    for(i = 0; i < n; i++){
        printf("%d%10.2f\n", p->num,p->score);
        p = p->next;
    }
    system("pause");
}

同时贴出一位网友给我的另一段代码:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
 
struct student {
    int num;
    float score;
    struct student *next;
};
 
struct student *creat(){
    struct student *p, *curr;
    int num;
    float score;
    struct student *head = (struct student *)malloc(sizeof(struct student));
    if(!head) return NULL;
    head->next = NULL;
    curr = head;
    printf("Please enter:num(-1 to break) and score\n");
    scanf("%d", &num);
    while(num != -1){
        scanf("%f", &score);
        p = (struct student *)malloc(sizeof(struct student));
        if(!p) return head;
        p->num = num;
        p->score = score;
        p->next = NULL;
        curr->next = p;
        curr = curr->next;
        scanf("%d", &num);
    }
    return head;
}
 
int main(){
    struct student *head, *p;
    head = creat();
    p = head->next;
    while(p){
        printf("%d%10.2f\n", p->num,p->score);
        p = p->next;
    }
    system("pause");
    return 0;
}

他在一些细节上都做了优化,学习学习~

5.对动态链表的操作

1)输出

输出可以参考上面的代码了。

2)删除

删除链表的算法就是输入学号,然后程序要检查是否和已有的结点对应,相等的话把那个结点删掉,不相等的话继续向后扫描,直到相等的时候执行删除的步骤,也就是将p2->next的结点赋值给p1->next而不是p1。如果要删除的是第一个结点,则使p1->head,如果扫描到最后还没有相等的结点,结束程序。

struct student *del(struct student *head,int num){
	if (head==NULL){
		printf("链表为空链表");
		return head;
	}
	p1=head;
	while (num!=p1->num&&p1->num!=NULL){
		p2=p1;
		p1=p1->next;
	}
	 if(num==p1->num){
		if (p1==head)head=p1->next;
		else p2->next=p1->next;
		
	}
	return (head);
}

3)插入

插入链表的算法:p0为要插入的结点的指针,将p2->next的值赋给p0,将p0->next的值赋给p1,改变原来p2->next=p1的情况即多出了一个新的结点。

struct student *insert (struct student *head,struct student *stu){
	struct student *p0;
	p0=stu;
	if (head==NULL){
		head=p0;
		p0->next=NULL;
	}
	else {								
		while ((p0->num>p1->num)&&(p1->next!=NULL)){	
			p2=p1;
			p1=p1->next;            		
		}
		if (p0->num<=p1->num){
			if (head=p1)head=p0;
			else p2->next=p0;		
			p0->next=p1;
		}
		else{
			p1->next=p0;
			p0->next=NULL;
		}
	}
	return(head);
}
本文共 1240 字,上次修改于 Jul 26, 2022,以 CC 署名-非商业性使用-禁止演绎 4.0 国际 协议进行许可。