一百行代码写一个简单的单链表
以下代码以C语言语法书写,读者可自行拷贝运行
如有疑问或需要源代码,Q:1286550014
此次单链表中包含五个函数:
void InsertHead(int data);//在头节点插入数据
void InsertTail(int data); //在尾部插入数据
void InsertIndex(int data, int index); //在指定Index下标处插入数据
void DeleteIndex(int index); //删除指定index下的数据
void ShowList(); //打印整个单链
二、程序开始:
①初始化一个结构体,用于表示每一个节点
typedef struct node {
int data; //节点内数据
struct node* next; //用于指向下一节点的指针
int length; //用于记录当前链表
}Node,*pNode;
②因为每回插入新数据都要申请节点,此处我们定义了一个返回值为pNode的函数
用于后面申请节点使用,避免了代码的重复书写
pNode createNode(int data) //创建节点函数,用于后面申请新节点使用,避免代码冗余
{
pNode pnew = (pNode)malloc(sizeof(Node));
pnew->data = data;
pnew->next = NULL;
return pnew;
}
③定义头指针与链表的长度变量
pNode pHead;//定义一个头结点指针
int length=0; //定义一个全局变量,用来表示单链表长度
④定义插入头结点函数
void InsertHead(int data) //在头结点处插入新数据
{
pNode pnew = createNode(data); //申请一个新节点
if (pHead == NULL) //如果头结点为空
{
pHead = pnew; //直接将新节点赋值给新节点
length += 1;
}
else //如果头节点不为空
{
pnew->next = pHead->next; //先将新节点指向头结点的下一节点
pHead->next = pnew; //再将头结点下一节点指针指向新节点
length += 1;
}
}
⑤定义插入尾节点函数
void InsertTail(int data)
{
pNode pnew = createNode(data); //申请新节点
if(pHead==NULL)
{
pHead = pnew; //如果头结点为空,直接将新节点给头结点
length += 1;
}
else
{
pNode p = pHead; //定义临时指针指向头结点
while (p->next) //循环遍历链表
{
p = p->next;
}
p->next = pnew; //将最后一个节点的指针指向新节点
length += 1;
}
}
⑥ 定义插入指定index下标出的函数
void InsertIndex(int data, int index) //在index位置插入数据,下标从0开始
{
if (index<0 || index>length) //如果输入的位置有误
{
printf("对不起,您输入的位置有误,请重新输入!\n");
}
else
{
pNode pnew = createNode(data);
if (index == 0)//如果是插入在第一个位置,需要单独判断
{
pnew->next = pHead;
pHead = pnew;
return;
}
else
{
int i = 0; //定义循环坐标从0开始
pNode p = pHead;
while (i<index - 1)//一直遍历到想要插入的位置
{
p = p->next;
i++;
}
pnew->next = p->next;//先将新节点指向指定位置的下一节点
p->next = pnew;//然后再将指定位置的前一节点的下一节点指点指向新节点
length += 1;
}
}
}
⑦定义删除指定index下标出的函数
void DeleteIndex(int index)//删除index下标出的数据
{
if (index<0 || index>length)//如果插入位置有误
{
printf("对不起,你输入的位置有误!\n");
}
else
{
pNode p = pHead;
if (index == 0)//如果删除的是头结点,特殊考虑
{
pHead = p->next;
free(p);
return;
}
for (int i = 0; i < index-1; i++)//寻遍遍历
{
p = p->next;
}
pNode temp = p->next;//定义第三指针
p->next = temp->next;//将删除位置前一节点指针指向删除位置的下一节点
free(temp);//释放删除位置处的节点
}
}
⑧打印整个链表
void ShowList()//打印整个单链表
{
if (pHead == NULL)
{
printf("对不起,链表为空,无法打印!\n");
}
else
{
pNode p = pHead;//定义辅助指针
while (p->next)//循环遍历打印
{
printf("%d->", p->data);
p = p->next;
}
printf("%d\n", p->data);
}
}
==================
到此为止所有的代码,已经实现,以下是我自己的主函数内容,读者可根据自己的需求
调用不用的函数实现不同的效果
int main()
{
InsertHead(1);//头插1
InsertTail(2);//依次尾插2,3,4
InsertTail(3);
InsertTail(4);
InsertIndex(100, 1);//在下标1出插入100
ShowList();
DeleteIndex(0);//删除下标0处的元素
ShowList();
ShowList();//打印链表
getchar();
getchar();
return 0;
}
运行的结果图如下