#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode,*LinkList;
/*头插法新建链表*/
LinkList CreateList1(LinkList& L)//list_head_insert
{
LNode* s; int x;
L = (LinkList)malloc(sizeof(LNode));//带头结点的链表
L->next = NULL;//L->data 里边没放东西
scanf("%d", &x);//从标准输入读取数据
//3 4 5 6 7 9999
while (x != 9999)
{
s = (LNode*)malloc(sizeof(LNode));//申请一个空间,强制类型转化
s->data = x;//把读取到的值,给新空间中的data成员
s->next = L->next;//让新节点的next指针指向链表的第一个元素(头结点之后的第一个元素)
L->next = s;//让s作为第一个元素
scanf("%d", &x);//读取标准输入
}
return L;
}
/*尾插法新建链表*/
LinkList CreateList2(LinkList& L)//list_tail_insert
{
int x;
L = (LinkList)malloc(sizeof(LNode));//带头节点的链表
//"LinkList s, r = L;"写法也是可以的,其中r代表链表表尾节点,指向链表尾部
//如果r不是表尾节点,需要自行指向NULL
LNode* s, * r = L;
//3 4 5 6 7 9999
scanf("%d", &x);
while (x != 9999)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
r->next = s;//让尾部节点指向新节点
r = s;//r指向新的表尾节点
scanf("%d", &x);
}
r->next = NULL;//尾节点的next指针赋值为NULL
return L;
}
/*打印链表中每个节点的值*/
void PrintList(LinkList L)
{
L = L->next;
while (L != NULL)
{
printf("%3d", L->data);//打印当前节点数据
L = L->next;//指向下一个节点
}
printf("\n");
}
/*查找第几个节点的值*/
LinkList GetElem(LinkList L, int i)
{
int j = 1;
LinkList p = L->next;//让p指向第一个节点
if (0 == i)
{
return L;//i是零就返回头结点
}
if (i < 1)
{
return NULL;//i是负值就返回空
}
while (p && j < i)
{
p = p->next;//让p指向下一个节点
j++;
}
return p;
}
/*按值查询*/
LinkList LocateElem(LinkList L, ElemType e)
{
LinkList p = L->next;
while (p != NULL && p->data != e)
{
p = p->next;
}
return p;
}
/*新节点插入第i位置*/
bool ListFrontInsert(LinkList L, int i, ElemType e)
{
LinkList p = GetElem(L, i - 1);//拿到要插入位置的前一个位置的地址值
if (NULL == p)
{
return false;//i不对
}
LinkList s = (LNode*)malloc(sizeof(LNode));//为新插入的节点申请空间
s->data = e;//要插入的值放入对应空间
s->next = p->next;
p->next = s;
return true;
}
/*删除第i个位置的元素*/
bool ListDelete(LinkList L, int i)
{
LinkList p = GetElem(L, i - 1);//查找删除位置的前驱节点
if (NULL == p)
{
return false;//要删除的位置不存在
}
LinkList q = p->next;
if (NULL == q)
{
return false;//要删除的节点不存在
}
p->next = q->next;//断链
free(q);//释放对应节点空间
q = NULL;//为了避免野指针
return true;
}
//线性表的链式表示
int main()
{
LinkList L;//链表头,是结构体指针类型
LinkList search;//用来存储拿到的某一个节点
//CreateList1(L);//输入数据可以为3 4 5 6 7 9999 头插法新建链表
CreateList2(L);//输入数据可以为3 4 5 6 7 9999
PrintList(L);//链表打印
search = GetElem(L, 2);//查找链表第二个位置的元素值
if (search != NULL)
{
printf("按序号查找成功\n");
printf("%d\n", search->data);
}
search = LocateElem(L, 6);//按值查询
if (search != NULL)
{
printf("按值查找成功\n");
printf("%d\n", search->data);
}
printf("----------------\n");
ListFrontInsert(L, 2, 99);//新节点插入第i个位置
PrintList(L);//链表打印
ListDelete(L, 4);//删除第4个节点
PrintList(L);
return 0;
}