LinkList.h
#define OK 1
#define FALSE 0
//#define ElemType int
typedef int Status;
typedef int ElemType;
typedef struct Node
{
ElemType data;//数据元素
struct Node * pNext;//指针遇指向下一个节点
}Node;
typedef Node * LinkList;
void createListHead(LinkList * L, int n);//随机产生n个元素的值,头插法建表
void createListTrail(LinkList * L, int n);//随机产生n个元素的值,尾插法建表
Status GetElem(LinkList L, int i, ElemType * e);//获取第i个元素,放入*e中
Status ListBackInsertIndex(LinkList L, int i, ElemType e);//在第i个元素后插入元素e
Status ListFrontInsertIndex(LinkList L, int i, ElemType e);//在第i个元素前插入元素e
Status ListBackInsertValue(LinkList L, ElemType a, ElemType e);//在第一个数据域的值为a的节点后插入e
Status ListFrontInsertValue(LinkList L, ElemType a, ElemType e);//在第一个数据域的值为a的节点前插入e
Status ListDeleteIndex(LinkList L, int i);//删除第i个元素
Status ListDeleteValue(LinkList L, ElemType e);//删除第一个值为e的节点
void ListPrint(LinkList L);//打印单链表
LinkList.c
#include"LinkList.h"
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void createListHead(LinkList * L, int n)
{
LinkList p = NULL;
time_t tms = 0;
srand((unsigned int)time(&tms));//设置随机数种子
*L = (LinkList)malloc(sizeof(Node));//先建立头结点
(*L)->data = 1;//使用头结点的数据域记录链表节点个数
(*L)->pNext = NULL;
for (int i = 0; i < n; i++)
{
p = (LinkList)malloc(sizeof(Node));
p->data = rand() % 100 + 1;//随机初始数据域,控制值在100内
p->pNext = (*L)->pNext;//头插法建表
(*L)->pNext = p;
(*L)->data++;//链表节点数加一
}
}
void createListTrail(LinkList * L, int n)//随机产生n个元素的值,尾插法建表
{
if ((*L)!= NULL)
return;
LinkList p = NULL, r = NULL;
time_t tms = 0;
srand((unsigned int)time(&tms));//设置随机数种子
*L = (LinkList)malloc(sizeof(Node));//先建立头结点
(*L)->data = 0;//使用头结点的数据域记录链表节点个数(不包括头结点)
(*L)->pNext = NULL;
r = *L;//记录尾节点
for (int i = 0; i < n; i++)
{
p = (LinkList)malloc(sizeof(Node));
p->data = rand() % 100 + 1;//随机初始数据域,控制值在100内
p->pNext = NULL;
r->pNext = p;
r = r->pNext;
(*L)->data++;//链表节点数加一
}
}
Status GetElem(LinkList L, int i, ElemType * e)//获取第i个元素,放入*e中
{
if (i < 1|| L == NULL || i > L->data )
return FALSE;
LinkList p = L;
for (int j = 0; j != i; j++)
p = p->pNext;
*e = p->data;
return OK;
}
Status ListBackInsertIndex(LinkList L, int i, ElemType e)//在第i个元素后插入元素e
{
if (L == NULL || i > L->data || i < 1)
return FALSE;
LinkList p1 = L,p2 = NULL;
for (int j = 0; j != i; j++)
p1 = p1->pNext;//寻找第i个节点,得到指向此节点的指针
p2 = (LinkList)malloc(sizeof(Node));
p2->pNext = p1->pNext;//新节点保存第i个节点的pNext
p1->pNext = p2;//覆盖第i个节点的pNext,使其指向新节点
p2->data = e;
L->data++;
return OK;
}
Status ListFrontInsertIndex(LinkList L, int i, ElemType e)//在第i个元素前插入元素e
{
if (L == NULL || i > L->data || i < 1)
return FALSE;
LinkList p1 = L, p2 = NULL;
for (int j = 0; j != i- 1; j++)
p1 = p1->pNext;//找到指向第i-1个节点的指针
p2 = (LinkList)malloc(sizeof(Node));
p2->pNext = p1->pNext;//设置新节点的pNext,使其指向第i个节点
p1->pNext = p2;//使第i-1个节点的pNext为新节点的地址
p2->data = e;
L->data++;
return OK;
}
Status ListBackInsertValue(LinkList L, ElemType a, ElemType e)//在第一个数据域的值为a的节点后插入e
{
if (L == NULL)
return FALSE;
LinkList pL = L->pNext,pNew = NULL;
for (; pL->data != a && pL->pNext != NULL; pL = pL->pNext);//寻找数据域为a的节点,用pL记录它的地址
if (pL->pNext == NULL)
printf("链表中无%d\n", a);
pNew = (LinkList)malloc(sizeof(Node));
pNew->pNext = pL->pNext;//将新节点的pNext设置为数据域为a的节点的pNext
pL->pNext = pNew;//用新节点的地址覆盖数据域为a的节点的pNext
pNew->data = e;
L->data++;
return OK;
}
Status ListFrontInsertValue(LinkList L, ElemType a, ElemType e)//在第一个数据域的值为a的节点前插入e
{
if (L == NULL)
return FALSE;
LinkList pNew = NULL,pFront = L;
//寻找数据域为a的节点的前一个节点的地址
for (; pFront->pNext->data != a && pFront->pNext->pNext != NULL; pFront = pFront->pNext);
if (pFront->pNext == NULL)
printf("链表中无%d\n", a);
pNew = (LinkList)malloc(sizeof(Node));
pNew->pNext = pFront->pNext;//设置新节点的pNext为数据域为a的节点的前一个节点的pNext
pFront->pNext = pNew;//设置数据域为a的节点的前一个节点的pNext为新节点的地址
pNew->data = e;
L->data++;
return OK;
}
Status ListDeleteIndex(LinkList L, int i)//删除第i个元素
{
if (L == NULL || i <1 || i > L->data || L->pNext == NULL)
{
printf("链表为空或超出下标范围!\n");
return FALSE;
}
LinkList pFront, ptemp;
pFront = L;
for (int j = 1; j < i; j++)
pFront = pFront->pNext;//寻找第i-1个节点的地址
ptemp = pFront->pNext;//记录指向第i个节点的指针,方便删除第i个节点
pFront->pNext = pFront->pNext->pNext;//重新设置第i-1个节点的指向,使其指向i+1个节点
L->data--;
free(ptemp);//删除第i个节点
}
Status ListDeleteValue(LinkList L, ElemType e)//删除第一个值为e的节点
{
if (L == NULL || L->pNext == NULL)
{
printf("链表为空!\n");
return FALSE;
}
LinkList pL = L, ptemp = NULL;
while (pL->pNext->data != e && pL->pNext != NULL)
pL = pL->pNext;//寻找值为e的节点,记录其前一个节点的地址
if (pL->pNext == NULL)
{
printf("没有找到符合要求的节点!\n");
return FALSE;
}
//重新设置值为e的节点的前一个节点的pNext,并删除值为e的节点
ptemp = pL->pNext;
pL->pNext = pL->pNext->pNext;
free(ptemp);
L->data--;
return OK;
}
void ListPrint(LinkList L)//打印单链表
{
if ( L == NULL)
{
printf("链表为空\n");
return;
}
printf("节点总数:%d\n", L->data);
for (LinkList pL = L->pNext; pL != NULL; pL = pL->pNext)
printf("value:%d,pNext:%p\n", pL->data, pL->pNext);
}
main.c
#include<stdio.h>
#include"LinkList.h"
int main()
{
LinkList L = NULL;
ElemType e = -1;
createListTrail(&L, 10);
//........................
ListPrint(L);
system("pause");
return 0;
}