参考链接: https://blog.csdn.net/men_wen/article/details/52877331
总结一下链表的基本操作,若有问题,欢迎讨论
1、基本概念
链表是一中常见的数据结构,通过一组任意的存储单元来存储线性表中的数据元素,这些存储单元可以是连续的也可以是不连续的,主要包含数据域(用于存储节点数据)和指针域(用于存储下一个指向节点的指针),结构如下:
typedef struct node{
int data;
struct node *next;
} NODE;
指针域中存储的是下一个节点的地址值
数据域存储的是这个节点保存的值
指针操作解读:
int var = 1;
int *p = &var;
// p变量中存储的值,值为var的地址
printf("%d, %d", p, &var);
// *可以读为指向的地址存储的值, 所以*p读为p指向的地址存储的值,值为var的值
printf("%d, %d", *p, var);
// &读为取地址,所以&p为取p的地址值,值为p的地址
printf("%d, %d", &p);
2、创建节点
NODE *initNode(NODE *pnode, int data){
pnode = (NODE *)malloc(sizeof(NODE));
pnode->data = data;
pnode->next = NULL;
return pnode;
}
3、创建链
前插法
将新节点放在链表头
//创建链(前插法)
NODE * createNodeList_bytail(NODE *phead, int data){
NODE *pnode = initNode(pnode, data);
NODE *ptmp = phead;
if(NULL == phead){
return pnode;
} else {
while(ptmp->next != NULL){
ptmp = ptmp->next;
}
ptmp->next = pnode;
}
return phead;
}
尾插法
将新节点放在链表尾
//创建链(尾插法)
NODE * createNodeList_byhead(NODE *phead, int data){
NODE *pnode = initNode(pnode, data);
NODE *ptmp = phead;
if(NULL == phead){
return pnode;
} else {
phead = pnode;
phead->next = ptmp;
}
return phead;
}
4、释放链
NODE * destroylist(NODE *phead){
NODE * tmp = NULL;
while(phead != NULL){
tmp = phead;
phead = phead->next;
free(tmp);
tmp = NULL;
}
}
5、链表长度
int listlen(NODE *phead){
int len = 0;
if(phead == NULL){
return len;
} else {
while(NULL != phead){
len++;
phead = phead->next;
}
return len;
}
}
6、遍历输出链表
void traversalList(NODE * phead){
int i = 0;
while(phead != NULL){
printf("%d, %d\n", ++i, phead->data);
phead = phead->next;
}
}
7、插入节点
前插节点
将新节点插入在被插入节点之前
NODE * insertNode_byhead(NODE *phead, int key, int data){
NODE *pnode = initNode(NULL, data);
NODE *ptmp = phead;
if (ptmp == NULL) {
return pnode;
}
if (ptmp->data == key) {
phead = pnode;
phead->next = ptmp;
} else
{
while(ptmp->next != NULL && ptmp->next->data != key){
ptmp = ptmp->next;
}
if (ptmp->next == NULL) {
printf("key not found\n");
} else
{
pnode->next = ptmp->next;
ptmp->next = pnode;
}
return phead;
}
}
后插节点
将新节点插入在被插入节点之前
NODE * insertNode_bytail(NODE *phead, int key, int data){
NODE *pnode = initNode(NULL, data);
NODE *ptmp = findnode(phead, key);
if(ptmp == NULL){
printf("key not found\n");
} else
{
if (ptmp->next == NULL) {
ptmp->next = pnode;
}else
{
pnode->next = ptmp->next;
ptmp->next = pnode;
}
}
return phead;
}
8、按值查找节点
NODE * findnode(NODE *p, int value){
if(NULL == p){ //链表为空,直接返回
return NULL;
}
while(p != NULL && p->data != value){
p = p->next;
}
if (p == NULL) {
return NULL;
} else
{
return p;
}
}
9、删除节点
NODE *deleteNode(NODE *phead, int key){
NODE *ptmp = phead;
if (ptmp == NULL) {
printf("key not found\n");
return NULL;
}
if (ptmp->data == key) {
phead = phead->next;
free(ptmp);
ptmp = NULL;
} else`在这里插入代码片`
{
while(ptmp->next != NULL && ptmp->next->data != key){
ptmp = ptmp->next;
}
if (ptmp->next == NULL) {
printf("key not found\n");
} else
{
NODE *p = ptmp->next;
ptmp->next = p->next;
free(p);
p = NULL;
}
return phead;
}
}
10、链表倒置
NODE * reverselist(NODE *phead){
NODE *pre = NULL;
NODE * tmp = NULL;
if (phead == NULL) {
printf("phead is NULL\n");
return NULL;
}
if (phead->next == NULL) {
return phead;
}
while(phead != NULL){
tmp = phead;
phead = phead->next;
tmp->next = pre;
pre = tmp;
}
return pre;
}
曾经在链表倒置这里迷糊过,倒置之后只是把每个节点的指针域的值改为了前一个节点,而节点本身所处位置的值并没有改变