首先来看一看单链表的定义(看看百度的)
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。[1]
再来看看我用c语言的描述吧
typedef struct Node
{
//数据域
int data;
//指针域
struct Node *pNext;
}NODE,*PNODE;
//NODE 等价于 struct Node
//*PNODE 等价于 struct Node *
数据域:用来存放数据
指针域:用来指向下一个结点(逻辑上相连)
如果看不懂,看看图吧:)
HEAD是头结点
HEAD指向的是首结点
创建单链表
思路:
我们可以一个一个的创建node最后串在一起。。。。
也可以先创建一个头,然后创建一下一个,并把最后一个结点的pNext指向下一个,如此循环,这里我们就要用一个指针一直指向链表的最后一个(尾指针),代码就是使用的这种
PNODE Create_Node(void)
{
int len, val;
PNODE List;
PNODE pHead = (PNODE)malloc(sizeof(NODE));//分配一个头结点
if(NULL == pHead)
{
printf("memory allocation failure");
exit(-1);
}
else
{
PNODE pTail = pHead; //尾指针指向头
pHead->pNext = NULL;
printf("please input the length of list: ");
scanf("%d",&len); //链表长度
for(int i=0; imalloc(sizeof(NODE));
if(NULL == p)
{
printf("memory allocation failure");
exit(-1);
}
else
{
printf("please input the value of list: ");
scanf("%d",&val);
//尾指针指向p
p->data=val;
pTail->pNext=p;
p->pNext=NULL;
pTail=p;
}
}
}
return pHead; //这里返回的是头结点 不是首结点
}
销毁链表,就是干掉这个链表从头到尾,什么都不留
思路:
从头开始释放,但是把头释放掉之后就找不到下一个结点,所以预先把下一个结点保存下来,然后删除,循环,有点绕,你可以简单的理解为过河拆桥
void destory_Node(PNODE pHead)
{
if(pHead == NULL)
return ;
PNODE temp = NULL;
while(pHead != NULL)
{
// printf("--------\n");
// print(pHead->data);
temp = pHead->pNext; // 先拿到下一个结点
free(pHead);
pHead = temp;
// if(pHead == NULL){
// printf("NULL");
// }
}
}
清空结点,只留下一个头结点,并让它指向NULL,意思就是把数据删了留下头
思路:直接从首节点销毁,把头结点指向NULL
PNODE clear_Node(PNODE pHead)
{
if(pHead->pNext == NULL)
return pHead;
destory_Node(pHead->pNext);
pHead->pNext = NULL;
return pHead;
}
循环打印 没什么好说的 直接上代码
这里写代码片void print(PNODE p)
{
p = p->pNext;
while(NULL != p){
printf("%d \n",p->data);
p = p->pNext;
}
}
注意长度是从有效节点开始的
int length_Node(PNODE pHead)
{
//这里的长度是有效data的值 所以头结点不算
int len = 0;
PNODE p = pHead->pNext;
while(p != NULL)
{
len++;
p = p->pNext;
}
return len;
}
思路:注意最前面有一个头结点 所以会-1,这样返回的就是第pos个结点了
PNODE find_Node(PNODE pHead, int pos)
{
int i = 0;
PNODE p = pHead;
while(NULL != p && i < pos-1)
{
p = p->pNext;
i++;
}
if(p->pNext == NULL || i > pos-1)
{
printf("error input pos");
exit(-1);
}
return p->pNext;
}
思路:第一个结点特殊处理,后面的直接在查询的基础上找到pos-1的结点,然后拿到pos,pos+1结点,删掉pos,把pos-1指向pos+1
bool delete_Node_pos(PNODE pHead, int pos)
{
PNODE pre,cur,next;
if(pos == 1)
{
next = pHead->pNext;
pHead->pNext = next->pNext;
free(next);
next = NULL;
return true;
}
pre = find_Node(pHead, pos-1);
if(pre->pNext != NULL)
{
cur = pre->pNext;
next = cur->pNext;
//pos前一位 指向pos后一位
pre->pNext = next;
//释放pos
free(cur);
cur = NULL;
return true;
}
else
{
printf("pos out of node");
}
return false;
}
思路:重点是找到pos-1的结点,所以第一个结点特殊处理,找到前一个结点后,把他的next指向新结点,新节点指向前一个结点指向的地方
bool insert_Node(PNODE pHead, int pos, int data)
{
PNODE p = NULL;
if(pos == 1){
p = pHead;
}
else
{
//找前一位
p = find_Node(pHead,pos-1);
}
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(pNew == NULL)
{
printf("memory allocation failure");
exit(-1);
}
printf("insert %d into Node->%d \n",data,pos);
//最后结果p(pos-1)->pNew(pos)->q(pos+1原第pos结点)
pNew->data = data;
PNODE q = p->pNext;
p->pNext = pNew;
pNew->pNext = q;
return true;
}
完整代码在这里
参考