入门结构体链表
6月 5, 2013
学完结构体发现这一章概括了这本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);
}