基于C++的单链表的实践
- 头文件的声明:
#pragma once
#ifndef header_h
#define header_h
#include<iostream>
using namespace std;
#define ok 1
#define error 0
#define null 0
#define overflow -2
typedef int status; //将status定义为int型类型 ,用于函数类型的定义
typedef int elemtype; //将elemtype定义为int型类型,用于结构体元素的类型定义
typedef struct lnode //结构体的创建
{
int length; //用来存放节点个数(可删除)
elemtype data; //用来存放元素(类型为整型)
struct lnode* next; //结构体指针,用来指向下一个节点
} lnode, * linklist; //结构体类型
status createlist(linklist& l, int n); //顺序创建单链表
status getelem(linklist l, int i, elemtype& e);//取单链表第i个元素的值给e
status listinsert(linklist& l, int i, elemtype e);//在单链表中第i个位置插入元素值e
status listdelete(linklist& l, int i, elemtype& e);//在单链表中删除第i个位置元素值并将其值赋值给e
status listlength(linklist l);//求单链表的长度e
int print(linklist l);//输出单链表
void homepage(); //输出选择页面
linklist server(linklist l);//将单链表倒置
#endif
主函数展示:
#include "header.h"
int main()
{
linklist l;
l = new lnode;
l->next = null;
l->length = 0;
int i, e, n, f;
while (1) {
homepage();
cin >> f;
system("cls");
switch (f) {
case 1:
cout << "请输入新建链表的节点数量:";
cin >> n;
createlist(l, n);
cout << "单链表为:";
print(l);
break;
case 2:
cout << "单链表为:";
print(l);
break;
case 3:
e = listlength(l);
cout << "单链表的长度为:" << e << endl;
break;
case 4:
cout << "请输入需要查询的节点位置:";
cin >> i;
getelem(l, i, e);
cout << "单链表第" << i << "个位置的元素数为:" << e << endl;
break;
case 5:
cout << "请输入要插入的节点位置以及元素:";
cin >> i >> e;
listinsert(l, i, e);
cout << "插入数据后的单链表为:";
print(l);
break;
case 6:
cout << "请输入要删除的节点位置:";
cin >> i;
listdelete(l, i, e);
cout << "删除数据后的单链表为:";
print(l);
break;
case 7:
l->next = server(l->next);
cout << "倒置之后的链表为:";
print(l);
break;
case 8:
return 0;
}
system("pause");
system("cls");
}
return 0;
}
/*************end*******************/
函数功能的实现:
#include "header.h"
/************beging******************/
status createlist(linklist& l, int n) //顺序创建单链表
{
linklist p, head; //定义结构体指针(即节点指针)
head = l; //将head指到链表的头节点
for (; head->next; head = head->next); //找到head的尾节点
cout << "请依次为各节点赋值:" ;
while (n--)
{
p = new lnode; //为p分配节点
cin >> p->data; //在该节点输入元素
p->next = null; //将p的下一个节点指向空
head->next = p; //将p接到head的尾部
head = p; //再一次将head指向尾节点
l->length++; //将链表长度加1
}
return 1;
}
status getelem(linklist l, int i, elemtype& e)//取单链表第i个元素的值给e
{
l = l->next; //将l指向链表的第一个有效元素(第一个节点为空节点)
for (int j = 1; j < i; j++) //找到第i个元素
l = l->next; //将p指向i+1个节点(即第i个元素所在的节点)
e = l->data; //将第第i个元素返回
return 1;
}
status listinsert(linklist& l, int i, elemtype e)//在单链表中第i个位置插入元素值e
{
linklist p, head; //定义结构体指针
head = l; //将head指向l所在的链表
for (int j = 1; head && (j <= i - 1); j++)
head = head->next;
//找到第i-1个节点,并保证该节点存在
p = new lnode; //创建新节点
p->data = e; //为新节点赋值
p->next = head->next; //将第i个节点之后的链表接到到p后面
head->next = p; //将p节点接到head后面
return 1;
}
status listdelete(linklist& l, int i, elemtype& e)//在单链表中删除第i个位置元素值并将其值赋值给e
{
linklist p, f; //定义结构体指针
f = l;
for (int j = 1; j <= i - 1; j++)
f = f->next;
//将f指向第i-1个有效节点(即要删除节点的前一个节点)
p = f->next; //将需要删除的节点赋给p
e = p->data; //将p中的元素给e返回
f->next = p->next; //将f指向f的下下一个节点(即要删除的后一个节点接到要删除的前一个节点的后面)
delete(p); //删除p节点
return 1;
}
status listlength(linklist l)//求单链表的长度e
{
int j;
l = l->next; //将l定位到第一个有效元素的位置(第一个节点无数据)
for (j = 0; l; j++)
l = l->next;
//将l依次到到尾部,并依次计数
return j; //返回j
}
int print(linklist l)//输出单链表
{
l = l->next; //将l定位到第一个有效元素的位置(第一个节点无数据)
if (!l) //判断是否链表是否为空
return 0;
while (l->next)
{
cout << l->data << " ";
l = l->next;
}
cout << l->data << endl;
//输出元素,并保证中间有空格输入,最后无空格且换行
return 1;
}
void homepage() //输出选择页面
{
cout << "输入1:为链表创建节点" << endl
<< "输入2:查询所有节点" << endl
<< "输入3:查询链表长度" << endl
<< "输入4:查询特定节点的元素" << endl
<< "输入5:插入元素" << endl
<< "输入6:删除节点" << endl
<< "输入7:倒置链表" << endl
<< "输入8:退出" << endl;
cout << "请选择:" ;
}
linklist server(linklist l) //将单链表倒置
//l链表中的节点全部为有效数据
//引用方式为l->next=server(l->next);
{
linklist head, p, q; //定义结构体指针
head = l;
p = q = null; //将p和q指向空
while (head) //判断head是否为空
{
q = head->next; //保存head的下一个节点
head->next = p; //将head的下一个指针指向p(即将p接到head后面)
p = head; //将p前移一个单位;
head = q; //将head指向之前保存的节点上
}
return p;
}