(一)什么是链表?
链表是一种常见的基础数据结构,是一种线性表,是一种在物理存储单元上非连续非顺序的存储结构。
链表有一系列节点构成,节点在运行时动态生成,每个节点包括数据域,数据域存储当前节点的信息,指针域存储下一个节点的手地址。
(二)为什么要使用链表?
顺序存储对空间的利用率不高;
内存随着时间的增加会找不到大块的顺序空间;
数组的大小只能是固定的,增加或删除都会移动大量数据;
链式存储大小可以伸缩;
链式存储利用率高。
(三)单向链表和双向链表
单向链表:每个元素包含一个指针域,该指针域指向该元素的直接后继元素。
双向链表:每个元素除了有一个指针域指向直接后继元素以外,还有一个指针指向其直接前驱元素。
如果把最后一个节点的指针指向第一个结点,同时把第一个结点的前向指针指向最后一个结点,这样就构成单向循环链表和双向循环链表。
c语言实现–单向循环链表操作
c语言实现–双向循环链表操作
(四)一个简单案例
这是一个小的系统,能实现几项简单的功能:创建链表、输入数据、查看信息、保存信息、读取信息、 删除结点、 查找信息
以下为部分代码:
1、结构体定义
typedef struct date
{
char name[32];
char pass[32];
char id[32];
}DATE;
typedef struct head
{
int len;
struct node * pfhead;
}Head,*PH;
typedef struct node
{
DATE date;
struct node * next;
}NODE,*PN;
2、创建链表
功能:构造一个链表头
传参:空
返回值:链表头
调用函数:无
PH create_list()
{
PH phead=NULL;
phead = (PH)malloc(sizeof(Head));
phead->pfhead=NULL;
phead->len=0;
return phead;
}
3、获取数据
功能:获取数据
传参:空
返回值:链表头
调用函数:无
PN getdate()
{
PN pnode=NULL;
pnode = (PN)malloc(sizeof(NODE));
printf(“请输入以下信息:\n”);
printf(“name:”);
scanf("%s",pnode->date.name);
getchar();
printf(“pass:”);
scanf("%s",pnode->date.pass);
getchar();
printf(“id:”);
scanf("%s",pnode->date.id);
getchar();
return pnode;
}
4、插入结点
功能:插入结点到链表中
传参:链表头
返回值:链表头
调用函数:获取数据函数 getdate()
PH insert_list(PH phead)
{
NODE* node;
int flag=0,i=0;
while(1)
{
if(flag!=0)
{
printf(“是否继续添加:1继续,0结束\n”);
printf(“你的选择:”);
scanf("%d",&i);
getchar();
if(i == 0)
break;
}
node = getdate();
node->next=phead->pfhead;
phead->pfhead=node;
phead->len++;
flag++;
}
return phead;
}
5、打印链表
功能:打印链表信息
传参:链表头
返回值:空
调用函数:无
void print_list(PH phead)
{
PN node=phead->pfhead;
while(node!=NULL)
{
printf("%-8s%-8s%-8s\n",node->date.name,node->date.pass,node->date.id);
node=node->next;
}
printf(“任意键退出:”);
getchar();
}
6、查找数据
功能:查找数据成员
传参:链表头
返回值:无
调用函数:无
void search_list(PH phead)
{
PN node=phead->pfhead;
char id[32];
printf(“请输入ID:”);
scanf("%s",id);
getchar();
while(node->next!=NULL && strcmp(node->date.id,id)!=0)
{
node = node->next;
}
if(strcmp(node->date.id,id)==0)
{
printf("%-8s%-8s%-8s\n",node->date.name,node->date.pass,node->date.id);
}
else
{
printf(“查无此人\n”);
}
printf(“任意键退出:”);
getchar();
return ;
}
7、删除结点
功能:删除结点
传参:链表头
返回值:链表头
调用函数:无
PH delete_list(PH phead)
{
PN node=phead->pfhead;
PN node2;
char id[32];
printf(“请输入ID:”);
scanf("%s",id);
getchar();
while(node->next!=NULL && strcmp(node->date.id,id)!=0)
{
node2=node;
node = node->next;
}
if(strcmp(node->date.id,id)==0)
{
if(node == phead->pfhead)
phead->pfhead=node->next;
else
node2->next=node->next;
phead->len–;
}
else
{
printf(“查无此人\n”);
}
return phead;
}
8、保存信息
功能:保存信息到文件
传参:链表头
返回值:无
调用函数:无
void save_list(PH phead)
{
FILE * fp;
if((fp=fopen(“phead”,“w”))==NULL)
{
printf(“打开文件失败\n”);
exit(1);
}
PN node=phead->pfhead;
while(node!=NULL)
{
fwrite(node,sizeof(NODE),1,fp);
node=node->next;
}
fclose(fp);
return ;
}
9、读取信息
功能:从文件中读取信息
传参:空
返回值:链表头
调用函数:无
PH read_list()
{
FILE * fp;
if( (fp=fopen(“phead”,“r”))==NULL)
{
printf(“打开文件失败\n”);
exit(1);
}
PH phead=(PH)malloc(sizeof(Head));
phead->pfhead=NULL;
PN node=(PN)malloc(sizeof(NODE));
while(fread(node,sizeof(NODE),1,fp)>0)
{
node->next=phead->pfhead;
phead->pfhead=node;
phead->len++;
node=(PN)malloc(sizeof(NODE));
}
fclose(fp);
return phead;
}
(四)例题分析
#include
#include <stdlib.h>
using namespace std;
class List;
class LinkNode{//链表节点类
friend List;//定义List为友元类
public:
LinkNode *link;//用来存储下一个节点的地址
int data;//需要节点存储的数据
public:
LinkNode(const int & item,LinkNode *ptr=NULL){data=item;link=ptr;}//构造函数赋初值
LinkNode(LinkNode *ptr=NULL){link=ptr;}//函数重载
~LinkNode(){};//析构函数,释放节点内存
};
class List{//链表类
public:
LinkNode *first;//头指针
int da[1000]={0};
public:
List(){first = new LinkNode();}
~List(){MakeEmpty();}//析构函数,释放链表内存
void MakeEmpty();
void input(int node_number);
void Sort();
void output();
};
void List::MakeEmpty(){
LinkNode *q;
while(first->link!=NULL){
q= first->link;
first->link = q->link;
delete q;
}
}
void List::input(int node_number){
LinkNode *newnode;
int val;
for (int i=0;i<node_number;i++){
cin>>val;
da[i] = val;
newnode = new LinkNode(val);
newnode->link = first->link;
first->link = newnode;
}
}
void List::output(){
LinkNode *q;
q = first;
while(q->link!=NULL){
q = q->link;
q->link = q->link;
cout<data<<endl;
}
cout<<endl;
}
void List::Sort(){
for(int i=0;da[i]!=0;i++){
for(int j=i+1;da[j]!=0;j++){
if(da[j]<da[i]){
int temp = da[i];
da[i] = da[j];
da[j] = temp;
}
}
}
}
int main()
{
List a,b;
int x,y,i,j;
int symbol=0;
cin>>x;//链表节点个数
a.input(x);
a.Sort();
cin>>y;
b.input(y);
b.Sort();
for(i=0;a.da[i]!=0;i++){
symbol = 0;
for(j=0;b.da[j]!=0;j++){
if(a.da[i]b.da[j]){symbol=1;}
}
if (symbol0){b.da[j]=a.da[i];}
}
b.Sort();
for(i=0;b.da[i]!=0;i++){cout<<b.da[i]<<endl;}
return 0;
}