链表的插入
头插法:
尾插法:
有序插入:
#include <stdio.h>
#include <stdlib.h>
//头插法 输入:4 5 10 2 6 8 输出:8 6 2 10 5 4
typedef struct student {
int num;
struct student *pNext;
}Student_t,*pStudent_t; //struct student*
void listHeadInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listTailInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listSortInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listPrint(pStudent_t pHead);
int main(){
pStudent_t phead = NULL, ptail = NULL;//头指针,尾指针
int num;
while (scanf("%d", &num) != EOF)
{
//listHeadInsert(&phead, &ptail, num);//插入新节点,头尾指针都要改变,
//故对头尾指针操作要取地址
//listTailInsert(&phead, &ptail, num);
listSortInsert(&phead, &ptail, num);
}
listPrint(phead);//值传递,没有去地址,不会改变这个值
}
//头插法 插进去的变成头?
void listHeadInsert(pStudent_t *ppHead, Student_t **ppTail, int val)//??理解一下这里面的参数
{
pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));//申请空间
pNew->num = val;
if (NULL == *ppHead)//判断链表是否为空
{
*ppHead = pNew;//新节点既给头节点,又给尾节点
*ppTail = pNew;
}
else {
pNew->pNext = *ppHead;//对ppHead取值才是一级指针才能拿到外面的值???
*ppHead = pNew;
}
}
//尾插法 输出和输出顺序一致,尾插,即新节点变成尾
void listTailInsert(pStudent_t *ppHead, Student_t **ppTail, int val)//??理解一下这里面的参数
{
pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));//申请空间
pNew->num = val;
if (NULL == *ppTail)//判断链表是否为空,用NULL==*ppHead也可以
{
*ppHead = pNew;//新节点既给头节点,又给尾节点
*ppTail = pNew;
}
else {
(*ppTail)->pNext=pNew;//对ppHead取值才是一级指针才能拿到外面的值???
//二级指针拿到一级指针才可以进行成员访问
*ppHead = pNew;
}
}
//有序插入 ????????这个比较复杂 输入3 6 9 3 7 -5 20
//输出-5 3 3 6 7 9 10 20
void listSortInsert(pStudent_t *ppHead, Student_t **ppTail, int val)
{//按从小到大 比如说 2 3 6之间插一个数
pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));
pStudent_t pCur = *ppHead,pPre;//这个需要理解一下????
//pPre相当于pStudent_t pPre;?????
pCur = pPre = *ppHead;//最开始都指向第一个节点(头节点),初始化,为了执行下面,介于头尾之间的情况
pNew->num = val;
if (NULL == *ppHead) {//*ppHead可以改成pCur 判断链表是否为空
*ppHead = pNew;//这里不能换成pCur
*ppTail = pNew;
}else if (val < pCur->num){ //小于头部节点,如1,即,插进去了变成头,头插法
pNew->pNext = *ppHead;//这里可以换成pCur
*ppHead = pNew;//但这里不可以换成pCur,要改变最初的那个
}
else{//插入的介于头尾节点之间,如4
while (pCur) {//插入到中间
//两个指针这里
if (pCur->num > val)//pCur所指的值大于要插入的值时
{//如果pCur->val大于插入的值时,执行这一句
pPre->pNext = pNew;
pNew->pNext = pCur;
break;
}
//如果pCur->num<val的值时,执行下面两句
pPre = pCur;//小弟先保存大哥的位置
pCur = pCur->pNext;
}
if (NULL == pCur)//大于尾节点的值,如8,要插入到尾部
{//尾插法
(*ppTail)->pNext = pNew;//这里的(*ppTail)->pNext等价于pPre->pNext
*ppTail = pNew;
}
}
}
void listPrint(pStudent_t pHead)
{
while (pHead != NULL)//打印,遍历,while循环
{
printf("%d", pHead->num);
pHead = pHead->pNext;
}
printf("\n");
}
链表的增删查改
#include <stdio.h>
#include <stdlib.h>
//头插法 输入:4 5 10 2 6 8 输出:8 6 2 10 5 4
typedef struct student {
int num;
float score;
struct student *pNext;
}Student_t, *pStudent_t; //struct student*
void listHeadInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listTailInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listSortInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listDelete(pStudent_t *ppHead, Student_t **ppTail, int val);
void listModify(pStudent_t pHead, int num, float score);
void listPrint(pStudent_t pHead);
int main() {
pStudent_t phead = NULL, ptail = NULL;//头指针,尾指针
int num;
float score;
while (scanf("%d", &num) != EOF)
{
// listHeadInsert(&phead, &ptail, num);//插入新节点,头尾指针都要改变,
//故对头尾指针操作要取地址
//listTailInsert(&phead, &ptail, num);
listSortInsert(&phead, &ptail, num);
}
listPrint(phead);//值传递,没有去地址,不会改变这个值
/*while (printf("please input delete num: "), fflush(stdout), scanf("%d", &num) != EOF)
{
listDelete(&phead, &ptail, num);
listPrint(phead);
}*/
while (printf("please input modify num and score:"), fflush(stdout), scanf("%d%f", &num,&score) != EOF)
{
listModify(phead, num, score);
listPrint(phead);
}
}
//头插法 插进去的新元素变成头?
void listHeadInsert(pStudent_t *ppHead, Student_t **ppTail, int val)//??理解一下这里面的参数
{
pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));//申请空间
pNew->num = val;
if (NULL == *ppHead)//判断链表是否为空
{
*ppHead = pNew;//新节点既给头节点,又给尾节点
*ppTail = pNew;
}
else {
pNew->pNext = *ppHead;//对ppHead取值才是一级指针才能拿到外面的值???
*ppHead = pNew;
}
}
//尾插法 输出和输出顺序一致,尾插,即新节点变成尾
void listTailInsert(pStudent_t *ppHead, Student_t **ppTail, int val)//??理解一下这里面的参数
{
pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));//申请空间
pNew->num = val;
if (NULL == *ppTail)//判断链表是否为空,用NULL==*ppHead也可以
{
*ppHead = pNew;//新节点既给头节点,又给尾节点
*ppTail = pNew;
}
else {
(*ppTail)->pNext = pNew;//对ppHead取值才是一级指针才能拿到外面的值???
//二级指针拿到一级指针才可以进行成员访问
*ppHead = pNew;
}
}
//有序插入 ????????这个比较复杂 输入3 6 9 3 7 -5 20
//输出-5 3 3 6 7 9 10 20
void listSortInsert(pStudent_t *ppHead, Student_t **ppTail, int val)
{//按从小到大 比如说 2 3 6之间插一个数
pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));
pStudent_t pCur = *ppHead, pPre;//这个需要理解一下????
//pPre相当于pStudent_t pPre;?????
pCur = pPre = *ppHead;//最开始都指向第一个节点(头节点),初始化,为了执行下面,介于头尾之间的情况
pNew->num = val;
if (NULL == *ppHead) {//*ppHead可以改成pCur 判断链表是否为空
*ppHead = pNew;//这里不能换成pCur
*ppTail = pNew;
}
else if (val < pCur->num) { //小于头部节点,如1,即,插进去了变成头,头插法
pNew->pNext = *ppHead;//这里可以换成pCur
*ppHead = pNew;//但这里不可以换成pCur,要改变最初的那个
}
else {//插入的介于头尾节点之间,如4
while (pCur) {//插入到中间
//两个指针这里
if (pCur->num > val)//pCur所指的值大于要插入的值时
{//如果pCur->val大于插入的值时,执行这一句
pPre->pNext = pNew;
pNew->pNext = pCur;
break;
}
//如果pCur->num<val的值时,执行下面两句
pPre = pCur;//小弟先保存大哥的位置
pCur = pCur->pNext;
}
if (NULL == pCur)//大于尾节点的值,如8,要插入到尾部
{//尾插法
(*ppTail)->pNext = pNew;//这里的(*ppTail)->pNext等价于pPre->pNext
*ppTail = pNew;
}
}
}
//删除
void listDelete(pStudent_t *ppHead, Student_t **ppTail, int deleteNum)
{
pStudent_t pCur = *ppHead, pPre;
pPre = pCur;
if (NULL == pCur)//链表的删除之前要判断是否为空链表
{
printf("查不到这个结点\n");//空的话不能删除,否则有问题
return;
}
else if (pCur->num == deleteNum)//删除的是头节点的话,即要删除节点的值等于deleteNum
{
*ppHead = pCur->pNext;//改变头指针,指向下一个节点
if (NULL == *ppHead)//但是如果删除的时候只有一个节点时
{//即删除后,头尾指针皆为NULL
*ppTail = NULL;
}
}
else {//删除的时中间或者尾部
while (pCur != NULL)
{
if (pCur->num == deleteNum)//如果pCur->num等于要删除的值时
{
pPre->pNext = pCur->pNext;
break;
}
pPre = pCur;
pCur = pCur->pNext;
}
if (NULL == pCur)//如果没有找到对应的节点的话
{
printf("没有找到这个要删除的数字\n");
return;
}
if (pCur == *ppTail)
{
*ppTail =pPre;
}
}
free(pCur);
pCur = NULL;
}
//链表的修改
void listModify(pStudent_t pHead, int num, float score)
{
while (pHead)
{
if (pHead->num == num)
{
pHead->score = score;
break;
}
pHead = pHead->pNext;
}
if (NULL == pHead)
{
printf("没有这个值\n");
}
}
void listPrint(pStudent_t pHead)
{
while (pHead != NULL)//打印,遍历,while循环
{
printf("%3d %5.2f\n", pHead->num,pHead->score);
pHead = pHead->pNext;
}
printf("\n");
}