个人认为看代码,debug是最好的学习方式
关于这部分的理论内容太多了,这里只用代码阐述思想
在这里需要注意的地方:
1、排序,注意交换数据区而不是指针,否则会出问题
2、删除节点的时候,让前节点指向当前节点的下一节点,然后释放当前节点
SinglyLinkedList.h
#pragma once
#include <windows.h>
#include <iostream>
using namespace std;
// 数据结构体
struct STDataInfo
{
char name[20]; // 姓名
char club[20]; // 俱乐部
char nation[20];// 国家
int price; // 身价
int num; // 号码
};
// 链表节点
struct stuLink
{
STDataInfo data; // 信息域
stuLink * next; // 指向下一节点的指针
};
class SinglyLinkedList
{
public:
SinglyLinkedList();
~SinglyLinkedList();
public:
// 创建新的节点
static stuLink* createNewNode(STDataInfo stData);
// 后向插入
static void insertAfter( stuLink* head, STDataInfo data);
//按照num查看前一个节点
stuLink* selectPreNodeByNum( stuLink* head, int num);
// 按照num查看当前节点
stuLink *selectNowNodeByNum(stuLink* head, int num);
// 按照名字查询前面一个节点
static stuLink *selectPreNodeByName(stuLink *head,char* name);
//按照名字查询当前节点
static stuLink* selectNowNodeByName( stuLink* head, char *name);
//删除节点--按照num删除
void deleteByNum(stuLink* head, int num);
//删除节点--按照name删除
static void deleteByName(stuLink*head, char *name);
//销毁链表
void freeLink(stuLink* head);
//循环打印链表
static void printLink(stuLink*head);
// 保存链表
static void save(stuLink * head);
// 加载链表
static void load(stuLink *head);
// 测试函数
//void TestLink();
private:
};
SinglyLinkedList.cpp
#include "SinglyLinkedList.h"
SinglyLinkedList::SinglyLinkedList()
{
}
SinglyLinkedList::~SinglyLinkedList()
{
}
stuLink* SinglyLinkedList::createNewNode(STDataInfo stData)
{
stuLink *NewNode = (stuLink*)malloc(sizeof(stuLink));
NewNode->data = stData;
NewNode->next = NULL;
return NewNode;
}
void SinglyLinkedList::insertAfter(stuLink* head, STDataInfo data)
{
if(NULL == head)
{
cout <<"当前节点不能为空" << endl;
return;
}
while(NULL != head->next)
{
head = head->next;
}
stuLink * newNode = createNewNode(data);
head->next = newNode;
}
// 返回前一个节点
stuLink* SinglyLinkedList::selectPreNodeByNum(stuLink* head, int num)
{
if(NULL == head) // 判断头结点是否为空
{
cout << "当前节点不能为空"<< endl;
return NULL;
}
stuLink *pre = head; // 前一个节点
head = pre->next;
while(NULL != head)
{
if(head->data.num == num)
{
return pre;
}
pre = head;
head = head->next;
}
return NULL;
}
stuLink * SinglyLinkedList::selectNowNodeByNum(stuLink* head, int num)
{
if(NULL == head) // 判断头结点是否为空
{
cout << "当前节点不能为空" << endl;
return NULL;
}
while(NULL!= head->next)
{
head = head->next;
if(head->data.num == num)
{
return head;
}
}
return NULL;
}
stuLink * SinglyLinkedList::selectPreNodeByName(stuLink *head, char* name)
{
if(NULL == head)
{
cout <<"头结点为空" << endl;
return NULL;
}
stuLink *pre = head;
head = head->next; // 当前节点
while(NULL != head)
{
if(0 == strcmp(head->data.name,name))
{
return pre;
}
pre = head;
head = head->next;
}
cout << "节点不存在"<< endl;
return NULL;
}
stuLink* SinglyLinkedList::selectNowNodeByName(stuLink* head, char *name)
{
if(NULL == head) // 判断头结点是否为空
{
cout << "当前节点"<< endl;
return NULL;
}
while(NULL != head->next)
{
head = head->next;
if(0 == strcmp(head->data.name,name))
{
return head;
}
}
return NULL;
}
void SinglyLinkedList::deleteByNum(stuLink* head, int num)
{
if(NULL == head)
{
return ;
}
stuLink *preNode = selectPreNodeByNum(head, num);
stuLink *delNode = preNode->next;
preNode->next = delNode->next;
free(delNode);
cout <<" 删除成功" << endl;
}
void SinglyLinkedList::deleteByName(stuLink*head, char *name)
{
if(NULL == head)
{
return;
}
stuLink *pPreNode = selectPreNodeByName(head, name);
stuLink *delNode = pPreNode->next;
pPreNode->next = delNode->next;
free(delNode);
cout << "节点删除成功"<< endl;
}
void SinglyLinkedList::freeLink(stuLink* head)
{
if(NULL == head)
{
return;
}
head = head->next;
while(NULL != head)
{
stuLink * tempNode = head->next;
free(head);
head = tempNode;
}
}
void SinglyLinkedList::printLink(stuLink*head)
{
if(NULL == head)
{
cout << "头节点为空" << endl;
return;
}
head = head->next;
while(NULL != head)
{
const char* pszName = head->data.name;
const char* pszClub = head->data.club;
const char* pszNation = head->data.nation;
int iPrice = head->data.price;
int iNum = head->data.num;
cout << "球员名"<<pszName << " ";
cout << "球衣号" << iNum << " ";
cout << "俱乐部" << pszClub << " ";
cout << "国籍" << pszNation << " ";
cout << "身价" << iPrice << endl;
head = head->next;
}
}
void SinglyLinkedList::save(stuLink * head)
{
if(NULL == head)
{
cout <<"头节点为空" << endl;
return;
}
FILE * fp = NULL; // 文件指针变量
fp = fopen("FootballPlayer.txt","w+");
if(NULL == fp)
{
cout << "保存失败"<< endl;
return;
}
head = head->next;
while(NULL != head)
{
fwrite(&head->data,sizeof(STDataInfo),1,fp);
head = head->next;
}
cout <<"保存成功" << endl;
fclose(fp);
}
void SinglyLinkedList::load(stuLink *head)
{
if(NULL == head)
{
cout << "头节点为空"<< endl;
return;
}
FILE * fp = NULL; // 文件指针变量
fp = fopen("FootballPlayer.txt", "r+");
if(NULL == fp)
{
system("echo > FootballPlayer.txt");
return;
}
while(1)
{
STDataInfo stInfo;
int iFlag = fread(&stInfo,sizeof(STDataInfo),1,fp);
if(iFlag <1)
{
break;
}
insertAfter(head, stInfo);
}
cout << "加载成功"<< endl;
fclose(fp);
}
/*
void SinglyLinkedList::TestLink()
{
// 初始化头结点
stuLink *head = NULL;
head = (stuLink *)malloc(sizeof(stuLink));
head->next = NULL;
// 新增节点
STStudent stKAKA;
strcpy(stKAKA.name,"KAKA");
stKAKA.num = 22;
insertAfter(head,stKAKA);
STStudent stINZAGHI;
strcpy(stINZAGHI.name, "INZAGHI");
stINZAGHI.num = 9;
insertAfter(head, stINZAGHI);
STStudent stPirlo;
strcpy(stPirlo.name, "Pirlo");
stPirlo.num = 21;
insertAfter(head, stPirlo);
STStudent stBuffon;
strcpy(stBuffon.name, "Buffon");
stBuffon.num = 1;
insertAfter(head, stBuffon);
int num = 21;
struct stuLink* nodeNow = selectNowNodeByNum(head, num);
char name[20];
strcpy(name, nodeNow->data.name);
//strcpy(name, pre->next->data.name);
cout << "Current Name is " <<name << endl;
}
*/
// PlayerInfoLink.h
#pragma once
#include "SinglyLinkedList.h"
class PlayerInfoLink
{
public:
PlayerInfoLink();
~PlayerInfoLink();
public:
// 新增加球员
static void addPlayer(stuLink * head);
// 删除
static void deletePLayer(stuLink * head);
// 修改球员身价
static void modifyPlayer(stuLink * head);
// 按照身价排序
static void SortByPrice(stuLink * head);
// 按照国家排序
// 按照俱乐部排序
// 菜单
static void PrintPlayerList();
private:
};
PlayerInfoLink.cpp
#include "View.h"
View::View()
{
m_pLinkHead = NULL;//创建头节点
m_pLinkHead = (stuLink*)malloc(sizeof(stuLink));//分配堆空间
m_pLinkHead->next = NULL;//让head的下一个节点为空
}
View::~View()
{
}
void View::TestLink()
{
stuLink* head = GetHeadNode();
// 加载本地数据
SinglyLinkedList::load(head);
// 用户操作
UserAction();
}
// 获取头结点
stuLink* View::GetHeadNode()
{
return m_pLinkHead;
}
void View::UserAction()
{
stuLink* head = GetHeadNode();
while(1)
{
PlayerInfoLink::PrintPlayerList();
cout << "请选择"<< endl;
int iActionType = 0; // 选择变量
scanf("%d", &iActionType);
while (getchar() != '\n');//吸收输入流多余的字符
switch(iActionType)
{
case E_MAIN_MENU_EXIT: // 保存数据然后退出
{
SinglyLinkedList::save(head);
return;
}
case E_MAIN_MENU_ADD_PLAYER: // 新增球员
{
PlayerInfoLink::addPlayer(head);
break;
}
case E_MAIN_MENU_DELATE_PLAYER: // 删除球员
{
PlayerInfoLink::deletePLayer(head);
break;
}
case E_MAIN_MENU_SORT_BY_PRICE: // 按照身价排序
{
PlayerInfoLink::SortByPrice(head);
break;
}
case E_MAIN_MENU_MODIFY_PLAYER_PRICE:// 修改
{
PlayerInfoLink::modifyPlayer(head);
break;
}
case E_MAIN_MENU_SHOW_ALL_PLAYER_INFO:// 显示所有球员信息
{
SinglyLinkedList::printLink(head);
break;
}
}
}
}
view.h
#pragma once
#include "SinglyLinkedList.h"
#include "PlayerInfoLink.h"
#include "ViewDefine.h"
class View
{
public:
View();
~View();
public:
void TestLink();
// 获取头结点
stuLink* GetHeadNode();
private:
// 执行用户操作
void UserAction();
public:
stuLink* m_pLinkHead; // 链表头节点
};
view.cpp
#include "View.h"
#include "ViewDefine.h"
#include "PlayerInfoLink.h"
#include "SinglyLinkedList.h"
View::View()
{
}
View::~View()
{
}
void View::TestLink()
{
stuLink* head = NULL;//创建头节点
head = (stuLink*)malloc(sizeof(stuLink));//分配堆空间
head->next = NULL;//让head的下一个节点为空
// 加载本地数据
SinglyLinkedList::load(head);
// 用户操作
UserAction();
}
void View::UserAction()
{
stuLink* head = NULL;//创建头节点
head = (stuLink* )malloc(sizeof(stuLink));//分配堆空间
head->next = NULL;//让head的下一个节点为空
while(1)
{
PlayerInfoLink::PrintPlayerList();
cout << "请选择"<< endl;
int iActionType = 0; // 选择变量
scanf("%d", &iActionType);
while (getchar() != '\n');//吸收输入流多余的字符
switch(iActionType)
{
case E_MAIN_MENU_EXIT: // 保存数据然后退出
{
SinglyLinkedList::save(head);
return;
}
case E_MAIN_MENU_ADD_PLAYER: // 新增球员
{
PlayerInfoLink::addPlayer(head);
break;
}
case E_MAIN_MENU_DELATE_PLAYER: // 删除球员
{
PlayerInfoLink::deletePLayer(head);
break;
}
case E_MAIN_MENU_SORT_BY_PRICE: // 按照身价排序
{
PlayerInfoLink::SortByPrice(head);
break;
}
case E_MAIN_MENU_MODIFY_PLAYER_PRICE:// 修改
{
PlayerInfoLink::modifyPlayer(head);
break;
}
case E_MAIN_MENU_SHOW_ALL_PLAYER_INFO:// 显示所有球员信息
{
SinglyLinkedList::printLink(head);
break;
}
}
}
}
main.c
#include <iostream>
#include <windows.h>
#include "SinglyLinkedList.h"
#include "View.h"
using namespace std;
// 创建新的节点
int main(int argc,char**argv)
{
//View::TestLink();
View m_View;
m_View.TestLink();
system("pause");
return 0;
}