目录
*链表的表示与实现*
前言
本文章以C语言的链表操作实现单链表的表示与实现,基本各种数据结构已具备,但并未完善代码的可读性及完善性,有兴趣的读者可以进行修改。
子函数
定义结构体
typedef struct LNode{
int data; //数据域
struct LNode *next;//指针域
}LNode,*LinkList;
main函数
int main()
{
LinkList list = InitList_L();
int data=0,n=0;
char index;
system("color b0");
while (1)
{
Menu();
int choose = _getch();
switch (choose)
{
case '1':
printf("请输入插入到第i个元素:");
scanf("%d",&n);
printf("请输入插入的元素:");
scanf("%d",&data);
ListInsert_L(list,n,data);
break;
case '2':
printList(list);
break;
case '3':
CreateList_H(list);
break;
case '4':
CreateList_R(list);
break;
case '5':
if(ListEmpty(list))
printf("链表为空!\n");
else
{
printf("链表不为空!链表内容为:");
printList(list);
}
break;
case '6':
printf("请输入删除的第i个元素:");
scanf("%d",&n);
data = ListDelete_L(list,n);
printf("第%d个元素:%d已删除!\n",n,data);
break;
case '7':
ClearList(list);
break;
case '8':
DestoryList_L(list);
printf("链表已销毁,是否初始化链表?(Y/y)\n");
setbuf(stdin, NULL);
scanf("%c",&index);
if(index == 'Y' || index == 'y')
list = InitList_L();
break;
case '9':
list = InitList_L();
break;
case 'L':
printf("链表的长度为:%d\n",ListLength_L(list));
break;
case 'G':
printf("请输入获取的第i个元素:");
scanf("%d",&n);
printf("获取链表第%d个元素为:%d\n",n,GetElem_L(list,n));
break;
case 'E':
printf("请输入查找的元素:");
scanf("%d",&data);
printf("获取链表元素为:%d的位置是在第%d个元素\n",data,LocateElem_L(list,data));
break;
case '0':
exit(0);//退出通讯录系统
}
system("pause");
system("cls");
}
return 0;
}
1.插入元素
/*
*插入元素e
*在L中第i个元素之前插入数据元素e
**/
void ListInsert_L(LinkList L,int i,int e){
LNode* p=L;
int j=0;
while(p && j<i-1){ //寻找第i-1个结点,p指向i-1结点
p=p->next;
++j;
}
if(!p || j>i-1) //i大于表长+1或小于1,插入位置非法
return;
LinkList s=(struct LNode*)malloc(sizeof(struct LNode));
s->data=e; //生成新结点s,将结点s的数据域置为e
s->next=p->next; //将结点s插入L中
p->next=s;
}
2.打印链表
//打印链表
void printList(struct LNode* headNode)
{
struct LNode* pMove = headNode->next;
while (pMove)
{
printf("%d-", pMove->data);
pMove = pMove->next;
}
printf("\n");
}
3.头插法
/*
*头插法
**/
void CreateList_H(LinkList L){
int data=0;
printf("请输入插入的元素:");
scanf("%d",&data);
struct LNode* newNode = createNode(data);
newNode->next = L->next;
L->next = newNode;
}
4.尾插法
/*
*尾插法
**/
void CreateList_R(LinkList L){
int data=0;
printf("请输入插入的元素:");
scanf("%d",&data);
struct LNode* newNode = createNode(data);
while(L->next!=NULL)
{
L=L->next;
}
L->next=newNode;
}
5.链表是否为空
//判断单链表是否为空
int ListEmpty(LinkList L)
{
if(L->next)
return 0;
else
return 1;
}
6.删除元素
/*
*删除元素e
*将L中第i个数据元素删除
**/
int ListDelete_L(LinkList L,int i){
LNode* p=L;
int j=0,data=0;
while(p->next && j<i-1){ //寻找第i个结点,并令p指向其前驱
p=p->next;
++j;
}
if(!(p->next) || j>i-1) return; //删除位置不合理
LinkList q=p->next; //临时保存被删结点的地址以备释放
p->next = q->next; //改变删除结点前驱结点的指针域
data = q->data;
free(q); //释放删除结点的空间
return data;
}
7.清空单链表
/*
*清空单链表L
*依次释放所有结点,并将头结点指针域设置为空
**/
void ClearList(LinkList L){ //将L重置为空表
LNode* p,*q;
p=L->next;
while(p){
q=p->next;
free(p);
p=q;
}
L->next = NULL; //头指针域为空
//return OK;
}
8.销毁单链表
/*
*销毁单链表L
*各个结点依次释放
**/
void DestoryList_L(LinkList L){
LNode* pMove;
while(L)
{
pMove = L;
L=L->next;
free(pMove);
}
}
*注:销毁单链表后需进行初始化单链表操作,否则链表未初始化不能进行操作。*
9.单链表初始化
//初始化单链表
LinkList InitList_L(){
LinkList L=(LinkList)malloc(sizeof(LNode)); //L=new LNode;
L->next=NULL;
return L;
}
10.获取链表长度
//初始化单链表
LinkList InitList_L(){
LinkList L=(LinkList)malloc(sizeof(LNode)); //L=new LNode;
L->next=NULL;
return L;
}
11.获取链表元素
/*
*获取线性表L中的某个数据元素内容,通过变量e返回
**/
int GetElem_L(LinkList L,int i){
LNode* p=L->next;
int data=0;
int j=1;
while(p&&j<i){ //向后扫描,直到p指向第i个元素或p为空
p=p->next;
++j;
}
if(!p || j>i) //第i个元素不存在
return;
data = p->data;
return data;
}
12.查找元素位置
/*
*查找元素位置
*在线性表L中查找值为e的数据元素
**/
int LocateElem_L(LinkList L,int data){
LNode* p=L->next;
int j=1;
while(p && p->data!=data){
p=p->next;
j++;
}
if(p) return j;
else
printf("该元素不存在!\n");
}
源代码
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
typedef struct LNode{
int data; //数据域
struct LNode *next;//指针域
}LNode,*LinkList;
//初始化单链表
LinkList InitList_L(){
LinkList L=(LinkList)malloc(sizeof(LNode)); //L=new LNode;
L->next=NULL;
return L;
}
//创建结点
LNode* createNode(int data)
{
LNode* newNode = (struct LNode*)malloc(sizeof(struct LNode));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
/*
*插入元素e
*在L中第i个元素之前插入数据元素e
**/
void ListInsert_L(LinkList L,int i,int e){
LNode* p=L;
int j=0;
while(p && j<i-1){ //寻找第i-1个结点,p指向i-1结点
p=p->next;
++j;
}
if(!p || j>i-1) //i大于表长+1或小于1,插入位置非法
return;
LinkList s=(struct LNode*)malloc(sizeof(struct LNode));
s->data=e; //生成新结点s,将结点s的数据域置为e
s->next=p->next; //将结点s插入L中
p->next=s;
}
/*
*头插法
**/
void CreateList_H(LinkList L){
int data=0;
printf("请输入插入的元素:");
scanf("%d",&data);
struct LNode* newNode = createNode(data);
newNode->next = L->next;
L->next = newNode;
}
/*
*尾插法
**/
void CreateList_R(LinkList L){
int data=0;
printf("请输入插入的元素:");
scanf("%d",&data);
struct LNode* newNode = createNode(data);
while(L->next!=NULL)
{
L=L->next;
}
L->next=newNode;
}
//判断单链表是否为空
int ListEmpty(LinkList L)
{
if(L->next)
return 0;
else
return 1;
}
/*
*删除元素e
*将L中第i个数据元素删除
**/
int ListDelete_L(LinkList L,int i){
LNode* p=L;
int j=0,data=0;
while(p->next && j<i-1){ //寻找第i个结点,并令p指向其前驱
p=p->next;
++j;
}
if(!(p->next) || j>i-1) return; //删除位置不合理
LinkList q=p->next; //临时保存被删结点的地址以备释放
p->next = q->next; //改变删除结点前驱结点的指针域
data = q->data;
free(q); //释放删除结点的空间
return data;
}
/*
*销毁单链表L
*各个结点依次释放
**/
void DestoryList_L(LinkList L){
LNode* pMove;
while(L)
{
pMove = L;
L=L->next;
free(pMove);
}
}
/*
*清空单链表L
*依次释放所有结点,并将头结点指针域设置为空
**/
void ClearList(LinkList L){ //将L重置为空表
LNode* p,*q;
p=L->next;
while(p){
q=p->next;
free(p);
p=q;
}
L->next = NULL; //头指针域为空
//return OK;
}
//求单链表L的表长
int ListLength_L(LinkList L){
LNode* p;
p=L->next; //p指向第一个结点
int i=0;
while(p){ //遍历单链表,统计结点数
i++;
p=p->next;
}
return i;
}
/*
*获取线性表L中的某个数据元素内容,通过变量e返回
**/
int GetElem_L(LinkList L,int i){
LNode* p=L->next;
int data=0;
int j=1;
while(p&&j<i){ //向后扫描,直到p指向第i个元素或p为空
p=p->next;
++j;
}
if(!p || j>i) //第i个元素不存在
return;
data = p->data;
return data;
}
/*
*查找元素位置
*在线性表L中查找值为e的数据元素
**/
int LocateElem_L(LinkList L,int data){
LNode* p=L->next;
int j=1;
while(p && p->data!=data){
p=p->next;
j++;
}
if(p) return j;
else
printf("该元素不存在!\n");
}
//打印链表
void printList(struct LNode* headNode)
{
struct LNode* pMove = headNode->next;
while (pMove)
{
printf("%d-", pMove->data);
pMove = pMove->next;
}
printf("\n");
}
void Menu()
{
printf("**********************************************\n");
printf("\t\t1.插入元素\n");
printf("\t\t2.打印单链表\n");
printf("\t\t3.头插法\n");
printf("\t\t4.尾插法\n");
printf("\t\t5.链表是否为空\n");
printf("\t\t6.删除元素\n");
printf("\t\t7.清空单链表L\n");
printf("\t\t8.销毁单链表L\n");
printf("\t\t9.初始化单链表L\n");
printf("\t\tL.链表长度\n");
printf("\t\tG.获取链表元素\n");
printf("\t\tE.查找元素位置\n");
printf("\t\t0.退出\n");
printf("**********************************************\n");
}
int main()
{
LinkList list = InitList_L();
int data=0,n=0;
char index;
system("color b0");
while (1)
{
Menu();
int choose = _getch();
switch (choose)
{
case '1':
printf("请输入插入到第i个元素:");
scanf("%d",&n);
printf("请输入插入的元素:");
scanf("%d",&data);
ListInsert_L(list,n,data);
break;
case '2':
printList(list);
break;
case '3':
CreateList_H(list);
break;
case '4':
CreateList_R(list);
break;
case '5':
if(ListEmpty(list))
printf("链表为空!\n");
else
{
printf("链表不为空!链表内容为:");
printList(list);
}
break;
case '6':
printf("请输入删除的第i个元素:");
scanf("%d",&n);
data = ListDelete_L(list,n);
printf("第%d个元素:%d已删除!\n",n,data);
break;
case '7':
ClearList(list);
break;
case '8':
DestoryList_L(list);
printf("链表已销毁,是否初始化链表?(Y/y)\n");
setbuf(stdin, NULL);
scanf("%c",&index);
if(index == 'Y' || index == 'y')
list = InitList_L();
break;
case '9':
list = InitList_L();
break;
case 'L':
printf("链表的长度为:%d\n",ListLength_L(list));
break;
case 'G':
printf("请输入获取的第i个元素:");
scanf("%d",&n);
printf("获取链表第%d个元素为:%d\n",n,GetElem_L(list,n));
break;
case 'E':
printf("请输入查找的元素:");
scanf("%d",&data);
printf("获取链表元素为:%d的位置是在第%d个元素\n",data,LocateElem_L(list,data));
break;
case '0':
exit(0);//退出通讯录系统
}
system("pause");
system("cls");
}
return 0;
}