单链表是一种重要的数据结构,掌握单链表是掌握数据结构的基础。
开始学习单链表:
这里附上在网上看到的有关单链表的删除和插入的图:
什么都不说,直接附上代码:
SingleList.h
#ifndef SINGLELIST_H_
#define SINGLELIST_H_
typedef char ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LinkList;//链表类型定义
/*初始化链表*/
LinkList* InitList();//&L是以应用方式调用L,可以修改指针L
/*释放链表*/
void DestroyList(LinkList *L);
/*判断链表是否为空*/
int ListEmpty(LinkList *L);
/*返回链表的个数*/
int ListLength(LinkList *L);
/*打印链表表*/
void PrintList(LinkList *L);
/*获取链表中第i个元素*/
ElemType GetElem(LinkList *L,int i);
/*获取链表中倒数第n个数据,返回节点指针*/
LinkList *GetReverse(LinkList *L,int n);
/*在链表中查找元素e,返回它的序号*/
int LocateElem(LinkList *L,ElemType e);
/*在链表的第i个位置插入元素e*/
int InsertList(LinkList *L,int i,ElemType e);
/*在链表中删除第i个元素*/
ElemType ListDelete(LinkList *L,int i);
#endif
SingleList.c
#include <stdio.h>
#include<malloc.h>
#include"SingleList.h"
/*初始化链表*/
LinkList* InitList()
{
LinkList *L;
L=(LinkList*)malloc(sizeof(LinkList));//创建头结点
L->next=NULL;
return L;
}
/*释放链表*/
void DestroyList(LinkList *L)//一个结点一个结点的释放
{
LinkList *p=L,*q=p->next;
while(q!=NULL)
{
free(p);
p=q;
q=p->next;
}
free(p);
}
/*判断链表是否为空*/
int ListEmpty(LinkList *L)
{
return (L->next==NULL);
}
/*返回链表的个数*/
int ListLength(LinkList *L)
{
LinkList *p=L;
int i=0;
while(p->next!=NULL)
{
i++;
p=p->next;
}
return i;
}
/*打印链表表*/
void PrintList(LinkList *L)
{
LinkList *p = NULL;
if(L ==NULL)
{
printf("there is no linklist!\n");
return 0;
}
p=L->next;//从第一个结点开始输出
while(p!=NULL)//
{
printf("%c\t",p->data);
p=p->next;
}
printf("\n");
}
/*获取链表中倒数第n个数据,返回节点指针*/
LinkList *GetReverse(LinkList *L,int n)
{
LinkList *ptr1,*ptr2;
ptr1=ptr2=L;//同时指向头节点
int i;
for(i=0;i<n;i++)
{
ptr2=ptr2->next;//ptr2比ptr1考前n个节点
}
while(ptr2!=NULL)//当ptr2到达末节点时,ptr1就是倒数第n个节点
{
ptr2=ptr2->next;
ptr1=ptr1->next;
}
return ptr1;
}
/*获取链表中的第i个元素*/
ElemType GetElem(LinkList *L,int i)
{
ElemType e;
LinkList *p=L->next;//p指向第一个结点
int j=0;
while(j<i&&p!=NULL)
{
j++;
p=p->next;
}
if(p==NULL)//如果链表为空只有头结点
{
return 0;
}
else
{
e=p->data;
return e;
}
}
/*在链表中查找元素e,e已经存放在链表中了的,返回它的序号*/
int LocateElem(LinkList *L,ElemType e)
{
LinkList *p=L->next;//p指向第一个结点
int n=0;
while(p!=NULL&&p->data!=e)
{
p=p->next;
n++;
}
if(p==NULL)//如果链表为空只有头结点
return 0;
else
return n;
}
/*在链表的第i个位置插入元素e*/
int InsertList(LinkList *L,int i,ElemType e)
{
LinkList *q = NULL;
int j=0;
while(j<i && L!=NULL)
{
j++;
L = L->next;
}
if(L == NULL)//没有找到第i-1个结点
return 0;
else//找到第i-1个结点
{
q = (LinkList*)malloc(sizeof(LinkList));//创建新结点
q->data = e;
q->next = L->next;//将*q插入到*L之后
L->next = q;
return 1;
}
}
/*在链表中删除第i个元素*/
ElemType ListDelete(LinkList *L,int i)
{
LinkList *p=L,*q;
int j=0;
ElemType e;
while(j<i&&p!=NULL)
{
j++;
p=p->next;
}
if(p==NULL)
return 0;
else
{
q=p->next;//q指向要删除的结点
if(q==NULL)//不存在第i个结点
{
return 0;
}
e=q->data;
p->next=q->next;//从单链表中删除*q结点
free(q);//释放被删除的结点
return e;
}
}
main.c
#include <stdio.h>
#include "SingleList.h"
int main()
{
LinkList *L = NULL;
ElemType e;
printf("(1)初始化单链表L\n");
if((L = InitList()) == NULL)
{
printf("init list wrong!\n");
system("pause");
return 1;
}
printf("(2)依次采用尾插入法插入a,b,c,d,e,g,h元素\n");
InsertList(L,0,'a');
InsertList(L,1,'b');
InsertList(L,2,'c');
InsertList(L,3,'d');
InsertList(L,4,'e');
InsertList(L,5,'g');
InsertList(L,6,'h');
printf("(3)输出单链表\n");
PrintList(L);
printf("(4)单链表的长度Length=%d\n",ListLength(L));
printf("(5)判断单链表是否为空\n");
if (ListEmpty(L))
{
printf("单链表为空\n");
}
else
{
printf("单链表不为空\n");
}
e = GetElem(L,4);
printf("(6)顺序表L的第4个元素为=%c\n",e);
printf("(7)顺序表中元素g的位置i=%d\n",LocateElem(L,'g'));
printf("(8)在第4个元素位置上插入f元素\n");
InsertList(L,4,'f');
printf("(9)输出顺序表\n");
PrintList(L);
printf("(10)删除顺序表中的第3个元素\n");
e = ListDelete(L,3);
printf("(11)输出顺序表L\n");
PrintList(L);
printf("(12)再在头结点处插入新结点\n");
InsertList(L,0,'m');
printf("(13)输出顺序表L\n");
PrintList(L);
printf("(14)释放顺序表L\n");
DestroyList(L);
return 0;
}
实验结果: