实验目的
掌握链表数据结构的建立及操作
实验内容
设计一个将输入数据建立成链表、并依次输出链表数据、利用原空间把链表反转的程序。
实验步骤
1.定义数据元素类型,链表结点及链表结构体
2.完成链表创建、销毁、插入、删除结点、获取结点值、遍历链表、反转结点函数
3.可以分步写代码和调试运行,如:主函数;创建、销毁;插入、删除结点;遍历链表;反转结点
4.进行部分反转,判断是不是链表回文
注:链表是否使用头结点,任选。
设计思路
本实验完成了创建链表,释放链表,遍历链表,增加结点,删除结点,获取结点值,复制链表,反转链表,判断链表回文等功能;创建链表是通过尾插法实现的,反转链表是利用原空间通过头插实现的,判断回文是先复制未反转过的链表,再把它和反转过的链表相比较,如果是一样的,则是回文。
运行代码
#include <stdio.h>
#include <stdlib.h>
//创建结构体
typedef struct LNode
{
int data;
LNode* next;
}LNode, * LinkList;
//创建链表
void create_list(LinkList& L, int n) {
int i;
LNode* p, * r;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
r = L;
printf("input list_elem:");
for (i = n; i > 0; --i) {//尾插法
p = (LinkList)malloc(sizeof(LNode));
scanf_s("%d", &(p->data));
r->next = p;
r = p;
//p->next = L->next;
//L->next = p;
}
r->next = NULL;
}
//释放链表
void free_list(LinkList& L) {
if (NULL == L) {
return;
}
LNode* p = L;
while (p = p->next) {
L->next = p->next;
free(p);
p = L;
}
free(L);
}
//遍历链表
void display_list(LinkList& L) {
LNode* p;
p = L;
while (p->next != NULL) {
printf("%d ", p->next->data);
p = p->next;
}
p->next = NULL;
printf("\n\n");
}
//反转链表
void invert_list(LinkList& L) {
if (NULL == L) {
return;
}
LNode* p = L->next;
LNode* q = p->next;
LNode* t = NULL;
p->next = NULL;
while (q != NULL) {
t = q->next;
q->next = p;
p = q;
q = t;
}
L->next = p;
}
//获取结点值
int getelem_list(LinkList& L, int i) {
LNode* p = L->next;
int j = 1;
while (p && j < i) {
p = p->next;
++j;
}
if (!p || j > i)return -1;
return p->data;
}
//在第i个结点插入e
void insert_list(LinkList& L, int i, int e) {
LNode* p = L;
int j = 0;
while (p && j < i - 1) {
p = p->next;
++j;
}
if (!p || j > i - 1)return;
LinkList s;
s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
}
//删除第i个结点
void delete_list(LinkList& L, int i) {
LNode* p = L;
int j = 0;
while (p->next && j < i - 1) {
p = p->next;
++j;
}
if (!p->next || j > i - 1)return;
LNode* q = p->next;
p->next = q->next;
free(q);
}
//判断是否回文
void palindrome_list(LinkList& L, LinkList& an_L) {
int j = 1;
LNode* p = L->next, * q = an_L->next;
while (p != NULL && q != NULL )
{
if (p->data == q->data) { p = p->next; q = q->next; }
else { j = 0; break; }
}
if (j == 0)printf("NO!\n\n");
else printf("YES!\n\n");
}
//复制链表
void copy_list(LinkList& L, LinkList& an_L,int n) {
int i;
LNode* p, * r,*x;
x = L->next;
r = an_L;
for (i = n; i > 0; --i) {//尾插法
p = (LinkList)malloc(sizeof(LNode));
p->data = x->data;
x = x->next;
r->next = p;
r = p;
//p->next = L->next;
//L->next = p;
}
r->next = NULL;
}
int main() {
LinkList L, an_L;
L = (LinkList)malloc(sizeof(LNode));
an_L = (LinkList)malloc(sizeof(LNode));
int n, de, in1, in2, get;
printf("input length:");//链表长度
scanf_s("%d", &n);
create_list(L, n);//创建链表
printf("1.create list:");
display_list(L);
printf("2.choose a position and a number to insert:");//插入结点
scanf_s("%d %d", &in1, &in2);
insert_list(L, in1, in2);
display_list(L);
printf("3.choose a position to delete:");//删除结点
scanf_s("%d", &de);
delete_list(L, de);
display_list(L);
printf("4.input a position to get its elem:");//获取结点值
scanf_s("%d", &get);
printf("its elem is:%d\n\n", getelem_list(L, get));
copy_list(L, an_L, n);//复制未反转的链表
printf("5.inverted list:");// 反转链表
invert_list(L);
display_list(L);//输出反转后的链表
printf("6.is palindrome? ");//判断回文
palindrome_list(L, an_L);
free_list(L);//释放链表
free_list(an_L);
return 0;
}
运行结果及分析
实验结果符合预期,完成了想要的各项功能。