作业应用:图书管理系统
结构定义:
struct student{
ll ISBN;//ISBN号码
string name;
ldb price;
struct student *next;
};
链表的初始化:
student *head = nullptr;
student *p_new = nullptr;
在每次引入新头后,可以添加如下代码,释放节点并防止野指针和空置指针
free(p);
p = nullptr;
计数功能:
//计数功能
int count(student *head){
int cnt = 0;
student *new_head;
new_head = head;
while(new_head !=NULL){
cnt ++;
new_head = new_head ->next;
}
return cnt;
}
查找功能:
按照ISBN或者书名搜索,返回的为节点地址,传递的为头结点和ISBN/书名,这里提供ISBN版本,不同之处仅在于pos的类型
//查找功能
//返回的是一个节点地址 传递的是一个头结点和目标ISBN
student * isbn_search(student *head,ll pos){
student *new_head;
new_head = head;
while(new_head!=NULL){
if(new_head->ISBN == pos){
return new_head;
}
new_head = new_head ->next;
}
return NULL;
}
按照书名搜索:
//按照书名搜索
student * bookname_search(student *head,string pos){
student *new_head;
new_head = head;
while(new_head!=NULL){
if(new_head->name == pos){
return new_head;
}
new_head = new_head ->next;
}
return NULL;
}
删除功能:ISBN和书名都可以
//ISBN删除功能
void ISBNremove(student **head,ll pos){
student *pb , *pf;
pf = pb = *head;
if(*head == NULL){
}
while(pb ->ISBN != pos && pb->next !=NULL){
pf = pb;
pb = pb ->next;
}
if(pb->ISBN == pos){
if(pb == *head){
*head = pb ->next;
}
else{
pf->next = pb -> next;
}
}
else{
cout << "节点不存在"<<endl;
}
}
//name删除功能
void nameremove(student **head,string pos){
student *pb , *pf;
pf = pb = *head;
if(*head == NULL){
}
while(pb ->name != pos && pb->next !=NULL){
pf = pb;
pb = pb ->next;
}
if(pb->name == pos){
if(pb == *head){
*head = pb ->next;
}
else{
pf->next = pb -> next;
}
}
else{
cout << "节点不存在"<<endl;
}
}
库查询(遍历):
//查询功能
void list_print(student *head)
{
student *now;
now = head;
while(now!= nullptr)
{
cout << now->ISBN<<" "<< now->name<<" "<<now->price<<endl;;
now = now->next;
}
}
一些杂七杂八:
void mainprint(){
cout << "——————————————————————————首页————————————————————————"<<endl;
cout <<"———————————————————输入对应数字进入对应操作———————————————————————————"<<endl;
cout <<"———————————————————首次使用请按9添加一本书籍———————————————————————————————————"<<endl;
cout <<"0.退出系统"<<endl;
cout <<"1.进入查询系统"<<endl;
cout <<"2.进入修改/增删系统"<<endl;
cout <<"9.系统初始化"<<endl;
cout <<"请输入:"<<endl;
}
void chaxunprint(){
cout <<"—————————————————————————查询操作系统———————————————————————————"<<endl;
cout <<"———————————————————输入对应数字进入对应操作———————————————————————————"<<endl;
cout <<"1.根据ISBN号查询书籍名称"<<endl;
cout <<"2.根据书籍名称查询ISBN号"<<endl;
cout <<"3.输出当前库所有书籍"<<endl;
cout <<"4.返回上一页"<<endl;
}
void xiugaiprint(){
cout <<"—————————————————————————修改/增删操作系统———————————————————————————"<<endl;
cout <<"———————————————————输入对应数字进入对应操作———————————————————————————"<<endl;
cout <<"1.添加新书籍"<<endl;
cout <<"2.根据ISBN删除书籍"<<endl;
cout <<"3.根据书名删除书籍"<<endl;
cout <<"2.根据ISBN修改书名"<<endl;
cout <<"3.根据书名修改ISBN"<<endl;
cout <<"4.返回上一页"<<endl;
}
插入功能:
动态分配新节点并输入新节点数据
student *p_new = new student();
cin >> p_new ->ISBN >> p_new ->name >> p_new ->price;
在有序的链表里插入(在有基础的书库上开始添加),利用ISBN或书名均可
此处提供ISBN版本
void isbn_insert(student ** head,student * pos){
student *pb ,*pf;
pb = pf = *head;
if(*head == nullptr){
*head = pos;
pos ->next = nullptr;
return;
}
while((pos ->ISBN >= pb->ISBN)&&(pb->next!= nullptr)){
pf = pb;
pb = pb ->next;
}
if(pos->ISBN < pb->ISBN){
if(pb == *head){
pos->next = *head;
*head =pos;
}
else{
pf ->next = pos;
pos->next = pb;
}
}
else{
pb ->next = pos;
pos ->next = nullptr;
}
}
排序功能:(ISBN)
//pf 是前一个节点 pb是后一个节点 temp是冒泡排序的辅助节点
// pf -> next = pb
void isbn_sort(student *head)
{
student *pb,*pf,temp;
pf=head;
if(head== nullptr)
{
cout <<"链表为空 无需排序"<<endl;
return ;
}
if(head->next == nullptr)
{
cout <<"单节点 无需排序" <<endl;
return ;
}
while(pf->next != nullptr)
{
pb=pf->next;
while(pb!= nullptr)
{
if(pf->ISBN > pb->ISBN)
{
//值域交换
temp=*pb;
*pb=*pf;
*pf=temp;
//指针域交换
temp.next=pb->next;
pb->next=pf->next;
pf->next=temp.next;
}
pb=pb->next;
}
pf=pf->next;
}
}
正常插入(适合在创建初期使用):
void add_to_list(student **p_head,student *pos)
{
student *p_mov = *p_head;
if(*p_head == nullptr)
{
*p_head = pos;
pos->next= nullptr;
}
else
{
//找到尾结点
while(p_mov->next!= nullptr)
{
p_mov=p_mov->next;
}
p_mov->next = pos;
pos->next = nullptr;
}
}
//数组模拟
void add(int x){
e[idx] = x;
ne[idx] = head;
head = idx;
idx++;
}
c++数组模拟单链表的实现,与传统的含指针域的单链表的不同之处在于,模拟链表由数组模拟而成,基本功能基本一致,使用动态链表时,每次创新节点的时候,都要new一次是非常慢的,在笔试和算法竞赛中使用后者模拟
本文的数组模拟链表的功能包括:创建(默认),遍历,节点查找,节点删除,插入节点
数组模拟版本:
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int head, e[N], ne[N], idx;
void init() {
head = -1 ;
idx = 0;
}
void add_to_head(int x) {
e[idx] = x;
ne[idx] = head;
head = idx;
idx++;
}
void add(int k, int x) {
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx;
idx++;
}
void remove(int k) {
ne[k] = ne[ne[k]];
}
int main() {
int m;
cin >> m;
init();
while (m--) {
int k, x;
char op;
cin >> op;
if (op == 'H') {
cin >> x;
add_to_head(x);
} else if (op == 'D') {
cin >> k;
if (!k) head = ne[head];
remove(k - 1);
} else {
cin >> k >> x;
add(k - 1, x);
}
}
for (int i = head; i != -1; i = ne[i]) cout << e[i] << ' ';
cout << endl;
return 0;
}