数据结构--链表(学生信息管理系统)

目录

一、链表

二、单项链表

三、双向链表

四、学生管理系统


一、链表

基本概念 : 链表一种线性的数据结构,通过指针将一个个零散的内存块连接起来,链表的每个内存块称为结点。

二、单向链表

单向链表的数据块分为两部分,一部分是数据,一部分是指针,指针指向下一个节点,所以只能从前向后遍历

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
typedef struct student_information
{   
    int    num;      //学号
    char    name[10];   //姓名
} student;
typedef struct chainlist
{
    student data;
    chainlist *next;
    chainlist *pre;
    
}chainlist;
typedef struct headnode
{
    int length;
    chainlist *first;
}headnode;
headnode *Creat(headnode *list)
{// 构造一个空链表
    list=new headnode;//产生一个仅有表头结点的链表
    list->first=NULL;//first的值设为空(NULL)值 
    list->length=0;
    return list;
}
bool insert(headnode *head,int k,student stu1)
{
    if (k < 0||k>head->length) 
        return false;
    int index=1;
    chainlist *current=head->first;
    while(index<k&&current)
    {
        index++;
        current=current->next;
    }
    chainlist *q=new chainlist;
    q->data=stu1;
    if(k>1)
    {
        q->next=current->next;//next存储current的next current的next指向原来下一个数据的地址 每一个节点有自己的地址,但也存储着下一个节点的地址 
        current->next=q;//current的next存储q的地址,相当于当前节点指向q 
    }
    else
    {
        q->next=head->first;
        head->first=q;
    }
    head->length++;
    return true; 
}
void Output(headnode *head)
{// 逐个地输出链表L中的数据元素
    chainlist *current=head->first;
    while (current)
    {
        if(current->data.num!=0)
        cout<<current->data.num<<current->data.name<<" ";
        current=current->next ;
    }
    cout<<endl;
}
int main(){
    int i=0;
    student stu1;
    headnode *l;
    l=Creat(l);
    cout<<"请输入学生数据\n";
    while(cin>>stu1.num)
    {
        if(stu1.num==0)
        break;
        else
        {
            cin>>stu1.name;
            insert(l,i,stu1);
            i++;
        }
        
        
    }
    Output (l);
    printf("共有学生%d人",i); 
    
}

三、双向链表

在学习完了单向链表之后,对单向链表有了自己的理解。数据是通过指针指向链接的,一个数据块分为三部分,一个存储数据,一个pre指针,一个next指针

通过pre和next将数据串在一起

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
typedef struct student_information
{   
    int    num;      //学号
    char    name[10];   //姓名
} student;
typedef struct chainlist
{
    student data;
    chainlist *next;
    chainlist *pre;
    
}chainlist;
typedef struct headnode
{
    int length;
    chainlist *first;
}headnode;
headnode *Creat(headnode *head)
{// 构造一个空链表
    head=new headnode;//产生一个仅有表头结点的链表
    head->first=NULL;//first的值设为空(NULL)值 
    head->length=0;
    return head;
}
bool insert(headnode *head,int k,student stu1)
{
    if (k < 0||k>head->length) 
        return false;
    int index=1;
    chainlist *current=head->first;
    while(index<k&&current)
    {
        index++;
        current=current->next;
    }
    chainlist *q=new chainlist;
    q->data=stu1;
    if(k>1)
    {
        q->next=current->next;
        q->pre=current;
        chainlist *p=current->next;
        if(p)
        p->pre=q;
        current->next=q;
    }
    else
    {
        q->next=head->first;
        q->pre=NULL;
        chainlist *p=head->first;
        if(p)
        p->pre=q;
        head->first=q;
    }
    head->length++;
    return true; 
}
void Output(headnode *head)
{// 逐个地输出链表L中的数据元素
    chainlist *current=head->first;
    while (current)
    {
        if(current->data.num!=0)
        cout<<current->data.num<<current->data.name<<" ";
        current=current->next ;
    }
    cout<<endl;
}
int main(){
    int i=0;
    student stu1;
    headnode *l;
    l=Creat(l);
    cout<<"请输入学生数据\n";
    while(cin>>stu1.num)
    {
        if(stu1.num==0)
        break;
        else
        {
            cin>>stu1.name;
            insert(l,i,stu1);
            i++;
        }
        
        
    }
    Output (l);
    printf("共有学生%d人",i); 
    
}

四、学生管理系统

在构建双向链表的基础上,增加了遍历链表,查询数据,删除节点,增加节点等功能。

运用了模板类,不会的话可以去看看黑马程序员的C++教程。

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <cstring>
#include<iomanip>
//#include"function.h"
//#include"choose_function.h"
using namespace std;
typedef struct student_information
{   
    char num[100];      //学号
    char name[100];   //姓名
    float score1 ;
    float score2;
    float score3;
    float aver;
} student;
typedef struct chainlist
{
    student data;
    chainlist *next;
    chainlist *pre;
    
}chainlist;
typedef struct headnode
{
    int length;
    chainlist *first;
}headnode;
typedef struct Data_elements_for_direct_and_direct_rear_drives
{		
	chainlist	*prenode;
	chainlist	*nextnode;
} resultnode;//返回直接前驱和直接后驱的数据元素的地址结果
class doublechainlist
{
	private :
		headnode *head;
	public :
		
		headnode* doublechianlist();
		bool insert(int k,student stu1);
		void output();
		bool deletenode(int k) ;
		bool search_information(char *k,student &stu2);
		bool input(doublechainlist list1,int &i,student stu1);
		void printmenuname() ;
		void printmenu();
		bool choose_function(doublechainlist list1,student stu1,char j,int &n,student &stu2);
		int lenth();
		bool search_before_and_after(char *k,int j,int i,student &stu3,student &stu4);
		void printsinglestudentinformation(student stu);
		
		
};
headnode* doublechainlist::doublechianlist()
{// 构造一个空链表
    head=new headnode;//产生一个仅有表头结点的链表
    head->first=NULL;//first的值设为空(NULL)值 
    head->length=0;
    return head;
}
bool doublechainlist::search_before_and_after(char *k,int j,int i,student &stu3,student &stu4) 
{

	chainlist *current =head->first;
	resultnode node1;
	int a=0;
	int b=0;
	while(current)
	{
		if(strcmp(current->data.num,k)==0)
		break;
		current=current->next;
	}
	node1.prenode=current;
	node1.nextnode=current;
	cout<<current->data.num;
	if(current)
	{
		while(a<j&&node1.prenode)
		{
			node1.prenode=node1.prenode->pre;
			a++;
		}
		stu3=node1.prenode->data;
		while(b<i&&node1.nextnode)
		{
			node1.nextnode=node1.nextnode->next;
			b++;
		}
		stu4=node1.nextnode->data;
		return true;
	}
	else
	return false;
 
}
int doublechainlist::lenth()
{
	chainlist *current = head->first;
	int n =0;
	while(current)
	{
		n++;
		current = current->next;
	}
	return n;
}
bool doublechainlist::choose_function(doublechainlist list1,student stu1,char j,int &n,student &stu2)
  //操作选择函数
{
    int k,i,g;
    char p[100];
	int pos;	//为什么pos不能定义为 unsigned 
    switch(j)
	{
			
	
			case '1' ://显示线性表中的数据元素
				//system("cls");
				output();
				//system("pause");		
				//system("cls");
				return true;
				break;
				
			case '2' ://初始化学生信息
				cout<<"请输入学生数据,学号+空格+姓名+空格+成绩1+空格+成绩2+成绩3,以学号为零结束\n\t";
				if(input(list1,n,stu1));
				return true;
				break;

			case '3' ://插入数据元素
				//system("cls");
				n=lenth();
				output();				
				cout<<"\n\t当前数据元素的下标范围:0---"<<n<<endl;
				printf("\n\t请输入要插入点的下标:");				
				cin>>k;
				if (k < 0||k>n )
				{
					cout <<"\n"<<"非法下标,请重新选择功能"<<endl;
					return true;
					break;
				}
				cout<<"请输入学生数据,学号+空格+姓名+空格+成绩1+空格+成绩2+成绩3,以学号为零结束\n\t";
				cin>>stu1.num>>stu1.name>>stu1.score1>>stu1.score2>>stu1.score3;
				if(insert(k,stu1))	
				{
					
					printf("插入成功!\n\n");
					cout<<"现在的学生表为:\n"; 
					output();
				}
				else
				printf("插入失败!\n\n");
				//system("pause");		
				//system("cls");
				return true;
				break;				
			case '4'://删除数据元素
				//system("cls");
				//output(L);
				n=lenth();
				cout<<"\n\t当前数据元素的下标范围:1---"<<n<<endl;
				printf("\n\t请输入要删除数据元素的下标:");				
				cin>>k;
				if (k < 1 )
				{
					cout <<"\n"<<"请重新选择"<<endl;
					//system("pause");
					//system("cls");
					return true;
					break;
				}
				if(deletenode(k))		
				{
					printf("删除成功!目前的学生表为:\n\n");
					output();
				}
				else
					printf("删除失败!\n\n");
				//system("pause");
				//system("cls");
				return true;
				break;	
			case '5'://查找数据元素
				//system("cls");
				cout<<"当前双向链表中的学生信息如下"<<endl; 
				output();	
				printf("\n\t请输入要查找的学生学号:");				
				cin>>p;	
				if(search_information(p,stu2))//返回x所在的数组位置下标
				{
					printf("查找成功!\n\n");
					printsinglestudentinformation(stu2);
				}
				else
					printf("\n查找失败!\n\n");			
				//system("pause");
				//system("cls");
				return true;
				break;

           case '6'://取序列第k个元素
				output();
				int j,i;
				char num[100];
				student stu3;
				student stu4;
				cout<<"查找某一学生的第n个前驱和第m个后继元素"<<endl; 
				printf("\n\t请输入学生学号:");				
				cin>>num;
	            printf("\n\t第几个前驱号:\n");
                cin>>j;
	            printf("\n\t第几个后继:\n");
                cin>>i;
				if (j < 1||i < 1 )
				{
					return true;
					break;
				}
				if(search_before_and_after(num,j,i,stu3,stu4))
				{
					printf("获取成功!\n\n");
					cout<<num<<"的第"<<j<<"个前驱元素是:\n\t\t";
					printsinglestudentinformation(stu3);
					cout<<num<<"的第"<<i<<"个后继元素是:\n\t\t";
					printsinglestudentinformation(stu4);
				}
				else
					printf("\n取出失败!\n\n");
				//system("pause");
				//system("cls");
				return true;
				break;
		
			
			case '0': 
				exit(0);
				break;
			default  :
				//cout <<"请重新选择"<<endl;
				//system("pause");
				//system("cls");
				return false;
				break;
		
			}//end switch
}
void doublechainlist::printmenuname()
     //我就是我 
{   
	//system("color FA");
	printf("\n\n\n\n\n\n\n");
	//system("color EA");
	printf("              *************************************************\n");
	//system("color FA");
	printf("                           学生成绩单的双向链表存储\n\n");
	printf("                           制作: paul_chen21\n");
	printf("                           班级:cpp\n");
	printf("                           学号: 20222022\n");
	printf("                           指导老师: @paul\n");
	//system("color EA");
	printf("              *************************************************\n");
	//system("color FA");
	printf("\n\n\n\t\t");
}
void doublechainlist::printsinglestudentinformation(student stu)
{
	
	cout<<"\n\n";
		cout<<" ┌────────────────────────────────────────────────────────────────┐"<<endl;
	cout<<" │                          成    绩    单                        │"<<endl;
	cout<<" ├──────────┬──────┬──────────┬──────────┬──────────┬─────────────┤"<<endl;
	cout<<" │          │      │          │          │          │             │"<<endl;
	cout<<" │ 学号     │姓 名 │  成绩1   │  成绩2   │  成绩3   │  平均成绩   │"<<endl;
	cout<<" │          │      │          │          │          │             │"<<endl;
	cout<<" ├──────────┼──────┼──────────┼──────────┼──────────┼─────────────┤"<<endl;
	stu.aver=(stu.score1+stu.score2+stu.score3)/3;
    cout<<" │"<<setw(10)<<stu.num<<"│"<<setw(6)<<stu.name<<"│"<<setw(10)<<stu.score1<<
    "│ "<<setw(9)<<stu.score2<<"│"<<setw(10)<<stu.score3<<"│"<<setw(13)<<stu.aver<<"│"<<endl;
    cout<<" │          │      │          │          │          │             │"<<endl;
	cout<<" └──────────┴──────┴──────────┴──────────┴──────────┴─────────────┘"<<endl;       

}
void doublechainlist::printmenu()    //菜单函数
{
	

	cout <<"\n\t\t"<<"请选择以下一个功能:"<<endl;
	cout <<"\n\t\t"<<"1.显示线性表中的数据元素."<<endl;
	cout <<"\t\t2.初始化双向链表,填入初始学生数据" << endl;
	cout <<"\t\t3.插入数据元素." << endl;
    cout <<"\t\t4.删除数据元素."<<endl;
    cout <<"\t\t5.查找数据元素."<<endl;
	cout <<"\t\t6.取某个学生的第n个前驱和第m个后继元素 "<<endl;
    //cout <<"\t\t6.给定某一学号x,能同时找到该学生第i个前驱的学生信息,以及该学生第j个后继的学生信息 "<<endl;
	cout <<"\t\t0.退出.\n"<<endl;
	cout <<"\t\t===============================\n"<<endl;	


}
bool doublechainlist::input(doublechainlist list1,int &i,student stu1)
{
	 
	bool flag;
	char a[100];
	while(cin>>a)
    {
        if(strcmp(a,"0")==0)
        	break;
        else
        {
        	strcpy(stu1.num,a);
        	cin>>stu1.name;
        	cin>>stu1.score1;
        	cin>>stu1.score2;
        	cin>>stu1.score3;
            flag=list1.insert(i,stu1);
            i++;
        }   
		 
    }
    if(flag)
    return true;
}
bool doublechainlist::search_information(char *k,student &stu2)
{
	chainlist *current =head->first;
	student stu1;
	while(current)
	{
	
		stu1=current->data;
		if(strcmp(stu1.num,k)==0)
		{
			stu2=current->data;
			return true;	
		}
		current=current->next;
		 
	}
	return false;
	
	
}

bool doublechainlist::insert(int k,student stu1)
{
    if (k < 0) 
        return false;
    int index=1;
    chainlist *current=head->first;
    while(index<k&&current)
    {
        index++;
        current=current->next;
    }
    if (k > 0 && ! current) 
		return false;
    chainlist *q=new chainlist;
    q->data=stu1;
    if(k)
    {
        q->next=current->next;
        q->pre=current;
        chainlist *p=current->next;
        current->next=q;
        if(p)
        p->pre=q;
        
    }
    else
    {
        q->next=head->first;
        q->pre=NULL;
        chainlist *p=head->first;
        if(p)
        p->pre=q;
        head->first=q;
    }
    head->length++;
    return true; 
}

void doublechainlist:: output()
{// 逐个地输出链表L中的数据元素
    chainlist *current=head->first;
    	cout<<"\n\n";
	cout<<" ┌────────────────────────────────────────────────────────────────┐"<<endl;
	cout<<" │                          成    绩    单                        │"<<endl;
	cout<<" ├──────────┬──────┬──────────┬──────────┬──────────┬─────────────┤"<<endl;
	cout<<" │          │      │          │          │          │             │"<<endl;
	cout<<" │ 学号     │姓 名 │  成绩1   │  成绩2   │  成绩3   │  平均成绩   │"<<endl;
	cout<<" │          │      │          │          │          │             │"<<endl;
	cout<<" ├──────────┼──────┼──────────┼──────────┼──────────┼─────────────┤"<<endl;
    if(!current)
		printf("当前双向链表中没有存储数据\n");
    while (current)
    {
        if(current->data.num!=0)
        current->data.aver=(current->data.score1+current->data.score2+current->data.score3)/3;
        cout<<" │"<<setw(10)<<current->data.num<<"│"<<setw(6)<<current->data.name<<"│"<<setw(10)<<current->data.score1<<
            "│ "<<setw(9)<<current->data.score2<<"│"<<setw(10)<<current->data.score3<<"│"<<setw(13)<<current->data.aver<<"│"<<endl;	
	 	cout<<" ├──────────┼──────┼──────────┼──────────┼──────────┼─────────────┤"<<endl;
        current=current->next ;
    }
    	
	//cout<<" │          │      │          │          │          │             │"<<endl;
	cout<<" └──────────┴──────┴──────────┴──────────┴──────────┴─────────────┘"<<endl; 
     
	
    cout<<endl;
}
bool doublechainlist::deletenode(int k)
{
	chainlist *p;
	if(k<1||!head->first)
	return false;
	chainlist *current = head->first;
	if(k==1)
	{
		p=current->next;
		if(p)
			p->pre=NULL;
		head->first=p;
	}
	else
	{
		chainlist *q=head->first;
		for(int index = 1;index<k&&q;index++)
		{
			q=q->next;
		}
		if(!q)
			return false;
		current = q;
		q=current->pre;
		p=current->next;
		q->next=p;
		if(p)
			p->pre=q;
	}
	delete current;
	return true;
	
}
int main(){
	//system("color 6B");
    int i=0;
    int m;
    int n=0;
    char a[10];
    int flag;
    student stu1;
    student stu2;
    
    doublechainlist list1;
    list1.doublechianlist();
    list1.printmenuname();
    //list1.printmenu();
	/*
    flag=list1.input(list1,i,stu1);
   
    list1.output ();
    cout<<"共有学生"<<i<<"人"<<endl; 
    n=i;
    cout<<"想删除第几位学生的信息?\n"; 
    if(flag)
    while(cin>>m)
	{
		if(m>n||m==0)
			break;
		list1.deletenode(m);
		n--;
		cout<<"是否结束删除(按0结束)"<<endl;
		 
    }
    list1.Output ();
    cout<<"共有学生"<<n<<"人"<<endl; 
    */
    list1.printmenu();
	while(1)
	{
		//system("cls");
		
		printf("\n\t请输入功能编号:");
		gets(a);	
       /*if(a[1]!='\0'&&a[1]!='\r')
		{
			cout <<"\n"<<"please re_choose"<<endl;
			//system("pause");
			//system("cls");
			continue;
		}*/
        //else
		//{
			if(a[0]=='0') 
				break;	
		if(list1.choose_function(list1,stu1,a[0],n,stu2))	
		list1.printmenu();	
		//}

	}    
    //system("PAUSE");
    return 0;
}


 

  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

paul_chen21

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值