一、非循环单链表插入节点伪算法
如上图所示,已知有一链表,要想在p所指向的节点的后面插入一个新的节点q,则有两种方法:
伪算法一:
t = p->pNext; p->pNext = q; q->pNext = t;伪算法二:
q->pNext = p->pNext; p->pNext = q;二、非循环单链表删除节点伪算法
如上图所示,已知有一链表,要想把p所指向的节点的后面的节点删除,则有伪算法:
t = p->pNext; //使t指向p节点后面将删除的节点,以便后面释放 p->pNext = p->pNext->pNext; free(t); //free(t)是为了防止内存泄露
三、用C语言实现
/* 2016年9月13日10:28:14 链表复习,创建链表和遍历链表 */ #include<stdio.h> #include<malloc.h> //malloc 函数在此头文件 #include<stdlib.h> //exit 函数在此头文件 typedef struct Node { int data; //数据域 struct Node * pNext; //指针域 } * PNODE, NODE; //函数声明 PNODE creat_list(void); void traverse_list(PNODE pHead); bool is_empty(PNODE pHead); int length_list(PNODE pHead); void sort_list(PNODE pHead); bool insert_list(PNODE pHead, int pos, int val); bool delete_list(PNODE pHead, int pos, int *pVal); int main(void) //主函数主要来测试各个函数正确性 { int val; PNODE pHead = NULL; pHead = creat_list(); //创建链表 traverse_list(pHead); //delete_list(pHead, 2, &val); insert_list(pHead, 1, 99); printf("插入后:\n"); traverse_list(pHead); // sort_list(pHead); // printf("排序后:\n"); // traverse_list(pHead); //printf("链表的个数为:%d\n", length_list(pHead)); // if(is_empty(pHead)) // printf("链表为空!\n"); // else // printf("链表不为空\n"); return 0; } PNODE creat_list(void) //创建链表 { int len; //用来存放节点的个数 int val; //用来临时存放数据域的值 int i; PNODE pHead = NULL; //头指针 pHead = (PNODE)malloc(sizeof(NODE)); //创建头结点,并使头指针指向头结点 if(NULL == pHead) { printf("内存分配失败,程序终止!\n"); exit(-1); } PNODE pTail = NULL; //尾指针 pTail = pHead; pTail->pNext = NULL; //注意此语句不能省 printf("请输入要创建节点的个数:\n"); printf("len = :"); scanf("%d", &len); printf("\n"); for(i = 0; i < len; ++i) { PNODE pNew = NULL; pNew = (PNODE)malloc(sizeof(NODE)); //创建一个新节点 if(NULL == pNew) { printf("内存分配失败,程序终止!\n"); exit(-1); } printf("请输入第%d个节点的是:", i+1); scanf("%d", &val); printf("\n"); pNew->data = val; //将输入的值赋给新节点的数值域 pTail->pNext = pNew; //使原来的链表的尾指针指向新节点 pNew->pNext = NULL; //注意此语句不能省 pTail = pNew; //更新尾指针 } return pHead; //返回头指针 } void traverse_list(PNODE pHead) //遍历链表并输出数据域的值 { PNODE p = pHead->pNext; while(NULL != p) { printf("%d\n", p->data); p = p->pNext; } return; } bool is_empty(PNODE pHead) //判断链表是否为空 { if(NULL == pHead->pNext) return true; else return false; } int length_list(PNODE pHead) //返回链表的长度 { int len = 0; PNODE p = pHead->pNext; while(NULL != p) { ++len; p = p->pNext; } return len; } void sort_list(PNODE pHead) //冒泡排序 { int i, j, t; int len = length_list(pHead); PNODE p, q; //因为链表没有下标,所以用定义了p和q方便链表交换 for(i = 0; i < len-1; ++i) //方法一 { for(j = 0, p = pHead->pNext; j < len-1-i; ++j, p = p->pNext) { q = p->pNext; if(p->data > q->data) //从小到大排序 { t = p->data; //只需要交换数据域的内容 p->data = q->data; q->data = t; } } } // for(i = 0, p = pHead->pNext; i < len-1; ++i, p = p->pNext) //方法二 // { // for(j = i+1, q = p->pNext; j < len; ++j, q = q->pNext) // { // if(p->data > q->data) //从小到大排序 // { // t = p->data; //只需要交换数据域的内容 // p->data = q->data; // q->data = t; // } // } // } return; } //我自己写的 bool insert_list(PNODE pHead, int pos, int val) //在pos位置上插入一个数据域为val的新节点,pos从1开始 { int i; PNODE p, t; if(pos < 0 || pos > length_list(pHead)) //先判断pos的位置是否有效 { return false; } else { PNODE pNew = (PNODE)malloc(sizeof(NODE)); //创建一个新节点 if(NULL == pNew) { printf("内存分配失败,程序终止!\n"); exit(-1); } pNew->data = val; p = pHead; for(i = 0; i < pos-1; ++i) //使p指向要删除节点的前一个节点 { p = p->pNext; } t = p->pNext; p->pNext = pNew; pNew->pNext = t; return true; } } /* //参考郝斌老师写的 bool insert_list(PNODE pHead, int pos, int val) { int i = 0; PNODE p = pHead; while (NULL!=p && i<pos-1) { p = p->pNext; ++i; } if (i>pos-1 || NULL==p) return false; //如果程序能执行到这一行说明p已经指向了第pos-1个结点,但第pos-1个节点是否存在无所谓 //分配新的结点 PNODE pNew = (PNODE)malloc(sizeof(NODE)); if (NULL == pNew) { printf("动态分配内存失败!\n"); exit(-1); } pNew->data = val; //将新的结点存入p节点的后面 PNODE q = p->pNext; p->pNext = pNew; pNew->pNext = q; return true; } */ //我自己写的 bool delete_list(PNODE pHead, int pos, int *pVal) //把位置pos的节点删除,并将删除的值用val返回,pos从1开始 { int i; PNODE p, t; if(pos < 0 || pos > length_list(pHead)) //先判断pos的位置是否有效 { return false; } p = pHead; for(i = 0; i < pos-1; ++i) //使p指向要删除节点的前一个节点 { p = p->pNext; } *pVal = p->pNext->data; t = p->pNext; p->pNext = p->pNext->pNext; free(t); //释放内存,防止内存泄漏 t = NULL; return true; } /* //参考郝斌老师写的 bool delete_list(PNODE pHead, int pos, int * pVal) { int i = 0; PNODE p = pHead; while (NULL!=p->pNext && i<pos-1) { p = p->pNext; ++i; } if (i>pos-1 || NULL==p->pNext) return false; //如果程序能执行到这一行说明p已经指向了第pos-1个结点,并且第pos个节点是存在的 PNODE q = p->pNext; //q指向待删除的结点 *pVal = q->data; //删除p节点后面的结点 p->pNext = p->pNext->pNext; //释放q所指向的节点所占的内存 free(q); q = NULL; return true; } */