链表入门

在数据结构的线性结构中,数组虽然很方便,但是它有很多弊端。

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;
}
}

}



原文地址:https://www.cnblogs.com/viplanyue/p/12700708.html