C单链表操作
头指针存放链表元素数量,头节点开始存放数据,尾节点指向NULL
list.h
#ifndef _LIST_H #define _LIST_H #include <stdio.h> #include <stdlib.h> #define DEBUG 0 typedef struct node{ int val; struct node *next; }Node; Node * l_malloc(); // 分配内存 Node * init(); // 初始化 void show(Node *list); // 显示链表元素 int lsearch_pos(Node *list,int n); // 左搜索 int rsearch_pos(Node *list,int n); // 右搜索 int find_val(Node *list,int val); // 值搜索 Node * insert(Node *list,int pos,int n); // 插入节点 Node * del_node(Node *list,int n); // 指定位置删除节点 Node * del_val(Node *list,int val); // 指定值删除节点 #endif
list.c
#include "list.h" /************************************* * 分配内存,当失败时重新尝试1次 *************************************/ Node * l_malloc(){ Node *p = NULL; int cnt = 3; do{ p = (Node *)malloc( sizeof(Node) ); }while( NULL == p && --cnt); // 当失败时重新尝试 if( 0 > cnt ){ perror("malloc"); exit(-1); // 内存分配失败,退出 } return p; } /************************************* * 初始化 *************************************/ Node * init(){ const int num = 8; int cnt = 0; Node *head = NULL; Node *pcur = NULL; Node *pnew = l_malloc(); head = pcur = pnew; // head->val = 0; // 头指针,值记录链表元素数量 for( ; cnt < num; cnt++ ){ pnew = l_malloc(); pnew->val = cnt; pcur->next = pnew; pcur = pnew; head->val++; } pcur->next = NULL; return head; } /************************************* * 显示 *************************************/ void show(Node *list){ while( NULL != list ){ printf("%d->",list->val); list = list->next; } printf("end\n\n"); } /************************************* * 从左开始搜索 *************************************/ int lsearch_pos(Node *list,int n){ if( n < 1 || n > list->val ){ // 超出链表值数量 printf("exceed length of list\n"); return -1; } for( int cnt = 0; cnt < n ; cnt++ ){ list = list->next; } return list->val; } /************************************* * 从右开始搜索 *************************************/ int rsearch_pos(Node *list,int n){ if( n < 1 || n > list->val ){ printf("exceed length of list\n"); return -1; } Node *pcur = list->next; // 定义2个指针:当前位置 Node *ptag = list->next; // 目标位置 for( int cnt = 0; cnt < n ; cnt++ ){ pcur = pcur->next; } // 使当前位置与目标位置间隔 n while( NULL != pcur ){ // 当前位置先移动到表尾,此时 ptag 即为要搜索的位置 pcur = pcur->next; // 同时移动2个指针 ptag = ptag->next; // } return ptag->val; } /************************************* * 从左开始搜索指定值 * 有值返回位置,无值返回-1 *************************************/ int find_val(Node *list,int val){ if( DEBUG ) printf("in find_val:\n"); int cnt = 1; int len = list->val; for( ; cnt <= len; cnt++ ){ list = list->next; if( DEBUG ) printf(" list->val:%d\n",list->val); if( val == list->val ){ return cnt; } } return -1; } /************************************* * 指定位置插入新值 *************************************/ Node * insert(Node *list,int pos,int n){ if( DEBUG ) printf("in insert:\n"); Node *pcur = list; Node *pnew = l_malloc(); pnew->val = n; for( int cnt = 1; cnt < pos && pcur->next ; cnt++ ){ // 到达指定位置或链表尾时退出 pcur = pcur->next; if( DEBUG ) printf(" pcur->val:%d\n",pcur->val); } if( NULL == pcur->next ){ // 到达链表尾部,测试空链表或负数运行正常化 pnew->next = NULL; // 当pos大于链表长度时,插入表尾 pcur->next = pnew; } else{ pnew->next = pcur->next; pcur->next = pnew; } list->val++; return list; } /************************************* * 指定位置删除值 *************************************/ Node * del_node(Node *list,int n){ if( n < 1 || n > list->val ){ printf("exceed length of list\n"); return list; } Node *pcur = NULL; Node *ptag = list; for( int cnt = 0; cnt < n ; cnt++ ){ pcur = ptag; ptag = ptag->next; } pcur->next = ptag->next; free(ptag); list->val--; return list; } /************************************* * 指定值删除节点 *************************************/ Node * del_val(Node *list,int val){ int n = find_val(list,val); if( -1 == n ){ // 无指定值,不删除 return list; } return del_node(list,n); }
main.c
#include "list.h" int main(){ Node *list = init(); show(list); int num = lsearch_pos( list, 2 ); printf("the 2th value is %d\n",num); show(list); num = rsearch_pos( list, 2 ); printf("the value from right 2th is %d\n",num); show(list); num = find_val( list, 5 ); printf("the value 5 is in %dth\n",num); show(list); list = del_node( list, 1 ); printf("after delete 1th value,the list is:\n"); show(list); list = del_val( list, 3 ); printf("after delete value 3,the list is:\n"); show(list); list = del_val( list, 100 ); printf("after delete value 100,the list is:\n"); show(list); for( int cnt = 10;cnt > 0;cnt -- ){ list = del_node( list, cnt ); printf("after delete %dth value,the list is:\n",cnt); show(list); } for( int cnt = 0;cnt <20 ;cnt ++ ){ list = insert( list, cnt % 5 ,rand() ); printf("after insert a value at %dth,the list is:\n",cnt); show(list); } list = insert( list, 6 ,99 ); printf("after insert a value at 6th,the list is:\n"); show(list); list = insert( list, -6 ,99 ); printf("after insert a value at -6th,the list is:\n"); show(list); }