链表入门
在数据结构的线性结构中,数组虽然很方便,但是它有很多弊端。
1.因为数组是利用连续内存空间进行数据的存取的,所以其长度有一定限制。
2.虽然高版本的编程语言中强化了数组的储存类型,但是,刚刚解除编程的人如果入门就接触这种“高级数组”无疑是一种非常不好的习惯。
3.数组一旦显式的被申明后,其大小就固定了,不能动态进行扩充。而链表则可以,可以动态生成节点并且添加到已有的链表后面。
4.在删除几个元素时,链表的优点更加明显,数组删除元素需要大规模移动数据,而链表只需改动被删除元素前一个元素的指向就可以。
5.对一个程序员来说,没有什么比自由重要了,而链表恰恰具备了这样一个特点。
特别是当今社会,是一个大数据时代,在百万乃至千万级大数据面前,由于第一个和第四个特性,链表毫无疑问完胜数组。
在很多教科书中,把链表的名字叫的很长很形象,很大程度上给初学者一种下马威的感觉,其实,你只要把很多教科书上链表的那些官方名字给改了,你会发现链表竟然如此简单!
链表无非就是一种数据结构,任何一种数据结构都是为了解决数据而存在的,而对数据的操作,无非就是增删查改。所以无论是数组,队列,栈,树,图,它们的基本功都是增删查改,当然,链表也不例外。
一个点就是一个对象,一条线就是一个链表/数组/栈/队列,n条线的集合就是一个树/图,所有数据的集合就是一个数据库。
数据库的操作难就难在查,
增得查到最后一个结点
删得查到目的结点的前一个结点(有其他思维,但本文采用这种方法)
改得查到目的结点
下面是C++实现的对链表的基本操作,都是入门级别的,初学者易懂:
#include<iostream>
#include<malloc.h>
#include<windows.h>
using namespace std;
struct Lines{
int id;
int grade;
Lines* pnext; //指向下一个结点的指针
};
void Menu(); //菜单函数
void Add(Lines* lines); //增
void Del(Lines* lines); //删
void Show(Lines* lines); //查
void Update(Lines* lines); //改
int main(int argc,char** argv){
Lines* head = NULL; //初始化结点对象
head = (Lines*)malloc(sizeof(Lines)); //为结点对象分配指定大小的堆内存
head->id = 0;
head->grade = 0;
head->pnext = NULL;
int SIGN;
while(true){
Menu();
cin >> SIGN;
switch(SIGN){
case 1:
Add(head);
break;
case 2:
Del(head);
break;
case 3:
Show(head);
break;
case 4:
Update(head);
break;
case 5:
exit(1);
break;
default:
cout << "输入有误,请重新输入" << endl;
break;
}
}
return 0;
}
void Menu(){
system("cls");
cout << "1.添加学生信息" << endl;
cout << "2.删除学生信息" << endl;
cout << "3.查找同学信息" << endl;
cout << "4.修改学生信息" << endl;
cout << "5.退出" << endl;
cout << endl << "请输入功能代号,进行下一步操作" << endl;
}
void Add(Lines* lines){
system("cls");
int id = 1;
int grade;
cout << "请输入学生成绩" << endl;
cin >> grade;
Lines* temp = (Lines*)malloc(sizeof(Lines));
temp->pnext = NULL;
while(lines->pnext != NULL){
lines = lines->pnext; 不是目的结点就一直往后找
id++;
}
temp->id = id;
temp->grade = grade;
lines->pnext = temp;
system("pause");
}
void Del(Lines* lines){
system("cls");
int sign;
cout << "请输入要删除学生的学号" << endl;
cin >> sign;
Lines* temp = NULL;
temp = (Lines*)malloc(sizeof(Lines));
temp->pnext = NULL;
while(lines->pnext != NULL){
if(lines->pnext->id == sign){
temp->pnext = lines->pnext;
lines->pnext = lines->pnext->pnext; //使目的结点的前一个指向目的结点的后一个,从而把目的结点孤立,最后释放,实现删除
free(temp->pnext);
free(temp);
}else{
lines = lines->pnext;
}
}
}
void Show(Lines* lines){
system("cls");
lines = lines->pnext;
while(lines != NULL){
cout << lines->id << " " << lines->grade << endl;
lines = lines->pnext;
}
system("pause");
}
void Update(Lines* lines){
system("cls");
int sign;
int grade;
cout << "请输入学生学号" << endl;
cin >> sign;
cout << "请输入新的成绩" << endl;
cin >> grade;
while(lines != NULL){
if(lines->id == sign){
lines->grade = grade;
break;
}else{
lines = lines->pnext;
}
}
}