学习用代码,记录自己复习的时候用。。
代码参考了 白皮肤的黑客 的文章,地址 https://blog.csdn.net/Davidluo001/article/details/46476221
下面贴代码。
#include "stdafx.h"
#include <stdio.h>
#include <malloc.h>
typedef int Elemtype;
typedef struct Node {
Elemtype data; //存放节点的数据
Elemtype num; //存放结点的顺序
struct Node *next; //存放指向下一个结点的指针
}List,*NodeList;
//创建一个链表//
NodeList Create_List() {
int len, i;
printf("请输入想要定义的链表长度len=");
scanf("%d", &len);
NodeList PHead; //定义一个头结点
PHead = (Node *)malloc(sizeof(Node));//动态为其分配内存空间
PHead->next = NULL;
NodeList PTail; //尾结点,永远指向末尾
PTail = PHead;
for (i = 0; i < len; i++) {
//循环创建结点
int value; //存放结点的值
printf("请输入第%d个结点的值value=", i + 1);
scanf("%d", &value);
NodeList New;
New = (Node *)malloc(sizeof(Node));
New->data = value;
New->num = i + 1;
New->next = NULL;
PTail->next = New;
PTail = New; //Tail永远指向尾巴
}
return PHead;
}
//遍历单链表//
void Traverse(NodeList PHead) {
//传入头结点
NodeList P;
P = PHead->next; //P指向第一个结点
while (P != NULL) {
printf("NO.%d->%d\t", P->num, P->data);
P = P->next;
}
printf("\n");
}
//判断链表是否为空链表//
bool IfEmpty(NodeList PHead) {
//同样也是传链表的头结点
//true表示是空链表,false表示不是空链表
if (PHead->next == NULL)
return true;
else
return false;
}
//获取链表的长度
int List_Num(NodeList PHead) {
NodeList P = PHead->next;//指向第一个结点
int num = 0;
while (P != NULL) {
num++; //长度加一
P = P->next;
}
return num;
}
//往列表中插入元素//
bool Insert_List(NodeList PHead, int pos, int value) {
//传入元素分别是列表头指针,插入的位置,插入元素的值
//先要判断插入的位置是否合法
//合法的位置传出true,不合法的传出false
int num;
num = List_Num(PHead);//表示列表的长度
if (pos > num+1 || pos <= 0) {
printf("输入的位置不合法,请重新输入\n");
return false;
}
//分配一个结点空间
NodeList PNew,P;
PNew = (Node *)malloc(sizeof(Node));
PNew->num = pos;
PNew->data = value;
PNew->next = NULL;
if (pos == 1) {
//插入第一个位置,即为头结点之后的结点
PNew->next = PHead->next;
PHead->next = PNew;
//接下来逐个修改之后的结点的编号(加一)
for (P = PNew->next; P != NULL; P = P->next)
P->num++;
return true;
}
else if (pos == num + 1) {
//插入到链表的末尾
P = PHead->next;
while (P->next != NULL)
P = P->next;//最后P会指向末尾结点
P->next = PNew;
return true;
}
else {
//插入到链表的中间
P = PHead->next;
while (P->num != pos-1)
P = P->next;//此时的后一个结点就应该是PNew
PNew->next = P->next;
P->next = PNew;
//之后要修改PNew->next及其之后的结点的num
P = PNew->next;
while (P != NULL) {
P->num++;
P = P->next;
}
return true;
}
}
//在列表中删除元素//
bool Delete_List(NodeList PHead, int pos, NodeList e) {
//从链表中删除编号为pos的结点并且用结点e返回
//首先判断输入是否合法
int num = List_Num(PHead);
NodeList P = PHead->next;//P指向第一个结点
NodeList P1; //用来指向P之前的一个结点
if (pos > num || pos <= 0)
//输入不合法
return false;
if (pos == 1) {
//删除第一个结点
PHead->next = P->next;
e = P;
//将除了第一个结点之外的结点编号减一
P = PHead->next;
while (P != NULL) {
P->num--;
P = P->next;
}
return true;
}
else if (pos == num) {
//删除最后一个结点
P = PHead->next;
P1 = PHead->next;
P = P->next;
while (P->next != NULL) {
P = P->next;//最后P指向最后一个结点
P1 = P1->next;
}
e = P;
P1->next = NULL;
return true;
}
else {
//删除中间的结点
P = PHead->next;//这里表示第一个结点
P1 = PHead->next;
P = P->next; //这里已经是第二个结点了
while (P->num != pos) {
P = P->next;
P1 = P1->next;
}
//此时P指向要删除的结点
P1->next = P->next;
e = P;
//P之后的结点num减一
P = P1->next;
while (P != NULL) {
P->num--;
P = P->next;
}
return true;
}
}
int main()
{
NodeList P,e;
int num;
bool ifsuccess; //用来记录返回值
char choose1 = 'Y',choose2 = 'Y';
P = Create_List();//P就是这个单链表的头结点
num = List_Num(P);
printf("列表的长度为%d\n", num);
Traverse(P);
//执行插入命令
while (choose1 == 'Y') {
//此时执行结点插入函数
int pos, value;
printf("请输入插入结点的位置:");
scanf("%d", &pos);
printf("请输入插入结点的值:");
scanf("%d", &value);
ifsuccess = Insert_List(P, pos, value);
if (ifsuccess == true) {
Traverse(P);
printf("继续插入输入Y,否则输入N:");
getchar();
scanf("%c", &choose1);
}
}
//执行删除命令
while (choose2 == 'Y') {
int pos;
printf("请输入要删除的结点的编号:");
scanf("%d", &pos);
ifsuccess=Delete_List(P, pos, e);
if (!ifsuccess) {
printf("输入不合法,请重新输入\n");
choose2 = 'Y';
}
else {
Traverse(P);
printf("继续删除请按Y,退出请按N:");
getchar();
scanf("%c", &choose2);
}
}
return 0;
}
下面是运行情况
最后有一个问题没有解决,就是在删除的时候用e来返回删除的结点信息,但是编译器总是说我在使用前没有定义,这个问题没法解决。。希望有大佬能够帮忙解决这个问题。