您的位置:首页 > 理论基础 > 数据结构算法

数据结构之动态单链表代码实现

2015-10-08 17:31 148 查看
链式存储结构:哪里有空位就放在哪里,只是让每个元素知道他下一个元素的位置在哪里

特点:用一组人的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。通过存储后继元素的存储地址来实现

存储数据元素信息的域称为数据域,把存储直接后继文职的域称为指针域。指针域中的存储的信息称作指针或链,这两部分信息组成数据元素的存储映像,称为结点(Node)

头指针:链表中第一个结点的存储位置

头指针与头结点的异同点:

头指针:头指针是指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针;头指针具有编址作用,所以常用头指针冠以链表的名字; 无论链表是否为空,头指针均不为空。头指针是链表的必要元素

头结点:头结点是为了操作的统一和方便而设立你的,放在第一元素的结点之前,其数据域一般无意义(也可存放链表的长度);有了头肩点。对在第一元素节点前插入结点和删除第一结点,其操作与其他家电的操作就统一了;头结点不一定是链表的必要元素

单链表结构与顺序存储结构优缺点:
存储分配方式:顺序存储结构用一段连续的存储单元依次存储线性表的数据元素
单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素
时间性能:查找——顺序结构O(1),单链表 O(n)
插入和删除 ——顺序存储结构需要平均移动表长一半的元素,时间为O(n);单链表 O(1)
空间性能——顺序存储结构 需要预分配存储空间,分大了,浪费,分小了容易发生上溢;单链表不需要分配存储空间,只要有就可以分配,元素个数不受限制
线性表用于频繁的查找,很少进行插入和删除操作;知道元素个数有多大时
单链表用于频繁的插入和删除;不知道多大或者变化较大时

#include<stdio.h>
#include<string.h>
#include<malloc.h>//动态分配函数所要用到的宏
typedef struct studentList//typedef的作用是为了用student来声明结构体(struct是声明结构体,自己可以看看书)
{
char name[20];//学生名字
int age;//学生年龄
struct studentList *next;//用于指向下一结点
}student;//student可以自己定义为其他名称,但是以后声明结构体的时候得用你定义的那个名称

student *create()//student开始起作用了,用它来声明一个结构体函数
{
student *head,*previous,*current;//声明三个指向结构体的指针,head为指向头指针,previous为上一指针,current是指向现在结构体的指针,链表的重要思想就是用指针把不是连续的空间串起来
head=NULL;
puts("let us create a student's list,please input first student's name:");
while(1)
{
current=(student *)malloc(sizeof(student));//分配空间
if(head==NULL)//第一次分配
{
previous=current;
head=current;l//头指针指向头结点
}
else
previous->next=current;//上一结点的指针指向新分配的空间地址
current->next=NULL;//把新分配的空间指针设为NULL,表示目前的末结点
scanf("%s",current->name);//给新空间的名字赋值
puts("please input the student's age(0 to quit):");
scanf("%d",¤t->age);//年龄赋值
if(current->age==0)//如果年龄为0 ,表示退出
break;
puts("please input the next student's name:");
previous=current;//又循环   分配空间
}
current->next=NULL;
return head; //返回链表的起始位置
}

student *print(student *head)//打印链表
{
student *current;
current=head;
puts("Now the list is followed:");
puts("name                age");
while(current->next!=NULL)//判断是否是末节点
{
printf("%-20s%d\n",current->name,current->age);
current=current->next;//指针后移一位
}
printf("%-20s%d\n",current->name,current->age);
return head;
}

student *add(student *head,student *end)//在末尾添加新结构
{
student *current;
current=head;
while(current->next!=NULL)//循环至末结点
current=current->next;
current->next=end;//添加
end->next=NULL;//把新添加进来的指针域设置为NULL
return head;
}

student *dele(student *head,int n)//删除年龄第一个为n的student结构体
{
student *previous,*current;
current=head;
while(current->next!=NULL&¤t->age!=n)//没有循环至末结点 并年龄不为n,就一直往下移动
{
previous=current;
current=current->next;
}
if(current->age==n)//判断是否是年龄为n(有可能是循环至末结点)
{
if(current==head)//判断是否是第一个结点,因为第一个结点和中间结点的处理方式不同
head=current->next;//head直接指向第二结点
else previous->next=current->next; //否则当前结点的指针域指向下结点的指针域(也就是下下结点开始位置)
}
else puts("not exit");
return head;
}

int main(void)
{
student *head,*end;
int n;
head=create();
print(head);
end=(student *)malloc(sizeof(student));
puts("let us add a student's information,please input name and age.");
printf("name:");
scanf("%s",end->name);
printf("age:");
scanf("%d",&end->age);
add(head,end);
print(head);
puts("please input the age of student you want to delete:");
scanf("%d",&n);
dele(head,n);
print(head);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: