今天妥妥的把单链表搞定,下面来回顾下链表的相关知识。
我认为,在单链表的多种操作中属创建链表最为繁琐,但是理清思路之后,便也觉得很有逻辑感。所以先从链表的创建开始说起。
链表的创建:
创建链表的思路呢主要是首先请用户输入需要创建的节点数,因为链表就是由一个一个的节点相互挂钩从而形成一条类似于铁链的链子(自我认为)。知道节点数后,则首先创建头指针,因为要找到一条链表就是通过头指针将他找到,创建完后我还需要创建一个尾指针,这个指针时时刻刻只向链表的最后一个节点,因为最开始还没有创建任何链表的节点所以就令头指针与尾指针都只向头节点pHead=pTail。之后则需要进入一个for循环,在循环里进行创建每个节点,在创建之前首先让用户输入给所创建节点的参数(即数据域的值) 然后创建一个新节点pNew。再讲参数付给pNew的数据域pNew->data=val。然后再将pNew插在尾节点后面pNew=pTail->pNext。然后再将pNew设置成尾指针,pTail=pNew。并令pNew->pNext==NULL。最后返回头指针pHead。
以下是创建链表的代码:
链表的遍历:
PNODE create()
{
PNODE pHead,pNew;
int i,val;
int len;
printf("输入创建节点个数 len = ");
scanf("%d",&len);
pHead=(PNODE)malloc(sizeof(NODE));
if(pHead==NULL)
{
printf("内存分配失败\n");
exit(-1);
}
PNODE pTail=pHead;
pTail->pNext=NULL;
for(i=0;i
dat=val;
pTail->pNext=pNew;
pNew->pNext=NULL;
pTail=pNew;
}
return pHead;
}
所谓链表的遍历就是把链表的所以数据查看一遍并且显示出来。所以只需要创建一个指针指向pHead->pNext,作循环,每次检测指针是否为空,如果不为空则输出数据域的数据,并且是指针p指向下一个节点p=p->pNext。
判断链表是否为空:
所谓判断链表是否为空则就是判断头节点后面有没有节点如果有则不为空否则为空,由于代码简单在这里就不贴了。
链表长度:
求链表长度就是看链表有多少个节点,算法同遍历一样只是将输出改为令一个整形变量加1。
链表的排序:
由于链表不像数组一样是连续存储的,是通过指针一个一个挂钩的,所以不能同数组排序一样对变量自增,但是可以运用c++的重构思想将i++转化成另一种形式,所谓i++既是将i指向下一个元素,在链表中既是指向下一个节点所以可以用p=p->pNext代替i++,只有这里需要注意,其他的基本算法和数组的排序还是一样的。创建2个结构指针来代替数组排序中的i和j。
链表的插入:
链表的插入这里用到的思想是先排除一切异常情况,这些异常情况就是如果插入的数字位置>链表的长度+1则不行。其次是要插入首先要知道所插入位置的前一个节点,所以这里定义一个指针p使它找到pos-1位置的节点,找到后就将p的后继给pNew,pNew的后继给pos位置上的节点。
插入代码如下:
bool insert(PNODE pHead,int pos,int val)
{
PNODE p=pHead;
int i=0;
while(p!=NULL&&i
pNext;
i++;
}
if(i>pos-1||p==NULL)
return false;
PNODE pNew=(PNODE)malloc(sizeof(NODE));
if(pNew==NULL)
{
printf("内存分配失败\n");
exit(-1);
}
pNew->dat=val;
pNew->pNext=p->pNext;
p->pNext=pNew;
return true;
}
链表的删除:
链表的删除和链表的插入基本一样,不过在删除的时候应该先用一个节点指针保存要删除的节点然后再释放这个指针,删除的算法思想是使pos-1的节点的后继直接指向pos+1节点。
删除代码如下:
bool delet(PNODE pHead,int pos,int *pVal)
{
PNODE p=pHead;
int i=0;
while(p->pNext!=NULL&&i
pNext;
i++;
}
if(p->pNext==NULL||i>pos-1)
return false;
PNODE q=p->pNext;
*pVal=q->dat;
p->pNext=p->pNext->pNext;
free(q);
q=NULL;
return true;
}