数据结构学习一(单链表的操作)
2012-10-23 17:46
621 查看
自己写的一个单链表的例子,注释写的不是特别好,里面可能代码的不是很好。新手入门可以看下。
包括链表的插入、删除、查找、合并、逆序
包括链表的插入、删除、查找、合并、逆序
#include <stdio.h> #include <stdlib.h> #define TYPE char #define FORMAT "%c" #define CROSSBORDER -1 #define NEGATIVE 100 //链表的一个节点 typedef struct list_node { TYPE value ; struct list_node * next; }lnode,*ptrlnode; //链表 typedef struct list { ptrlnode head ; int length; }list; int list_init(list *l) { l->length = 0; l->head = 0 ; return 0 ; } //链表分配失败的输出信息。 void print_memory_fail() { printf("Failed to allocate memory!\n"); } //初始化一个节点,将节点的值设置位,并且将分贝节点的地址返回value 2012-07-30 struct lnode * list_node(TYPE value ) { lnode * current = (lnode *)malloc(sizeof(lnode)); if(NULL == current ) {print_memory_fail();exit(0);} current->value = value; current->next = NULL; return current; } //将 value的值查出到链表l的末尾 int list_insert_tail(list *l,TYPE value) { ptrlnode tmp,item; item = l->head; tmp=(lnode *) malloc(sizeof(lnode)); if(NULL == tmp){printf("Failed to allocate memory!\n");exit(0);}; tmp->value = value; tmp->next = NULL ; //检查链表是否为空 if(item) { while(item->next) { item= item->next; } item->next = tmp;l->length++; } else { l->head = tmp;l->length =1;} return 0; } //l:节点n所在的链表,n:在其后面添加节点了, value:要插入节点值 2012-07-30 int list_insert_node_tail(list * l,ptrlnode n , TYPE value) { ptrlnode tmp_node ; tmp_node = (lnode *)malloc(sizeof(lnode)); if(NULL == tmp_node ){printf("Failed to allocate memeory!\n");exit(0);} tmp_node ->value = value ; tmp_node ->next = n->next; n->next = tmp_node ; l->length ++; return 0; } //l:节点n所在的链表,n:在其后面添加节点了, value:要插入节点值 2012-07-30 int list_insert_node_location(list * l,lnode *current , unsigned int loc) { lnode * pre_node; int i; if(0>=loc || l->length < loc) { printf("Cross-border!\n"); return CROSSBORDER; } else { if(1 == loc) { current->next=l->head; l->head =current; l->length++; return 0; } pre_node = l->head; for(i=1;i<loc;i++) { pre_node = pre_node->next ; } current->next = pre_node->next; pre_node->next = current ; l->length ++; } return 0 ; } //在链表l中的current节点后面添加节点insert节点 2012-07-30 int list_insert_node(list *l,lnode * current,lnode * insert) { insert ->next = current->next ; current->next =insert ; l->length++; return 0; } //在将value的值新建一个节点并且作为链表的头,其余节点后移 int list_insert_head(list *l,TYPE value ) { ptrlnode tmp_node; tmp_node=(lnode *) malloc(sizeof(lnode)); if(NULL == tmp_node){printf("Failed to allocate memory!\n");exit(0);}; tmp_node ->value = value ; l->length++; tmp_node->next=l->head; l->head = tmp_node; return 0 ; } //在链表l中的loc新建一个节点并且值为n。其余节点后移(包括本节点) int list_insert_location(list *l,int loc,TYPE value) { ptrlnode tmpnode =NULL; ptrlnode pre_node=NULL; int i; if(0>=loc || l->length < loc) { printf("Cross-border!\n"); return CROSSBORDER; } else { tmpnode = (lnode *) malloc (sizeof(lnode)); if(NULL==tmpnode){printf("Failed to allocate memory!\n");exit(0);} tmpnode->value = value ; if(1 == loc) {tmpnode->next = l->head;l->head=tmpnode;l->length++;return 0;} pre_node = l->head; for(i=1;i<loc;i++) { pre_node = pre_node->next ; } tmpnode->next = pre_node->next; pre_node->next = tmpnode ; l->length ++; } return 0 ; } //查询value值在链表l中出现的次数,返回值value出现的次数,0没有出现,最多出现unsigned int unsigned int list_find_value_count(list l,TYPE value) { int i ,count=0; for(i=0;i<l.length;i++) { if(value == l.head->value)count ++; l.head = l.head->next; } return count; } //查询值value在链表l中第一次出现的位,没有出现的值返回0 int list_find_value_first_location(list l,TYPE value) { int i; for(i=0;i<l.length;i++) { if(value == l.head->value) return i+1; l.head = l.head->next; } return 0; } //查询值value在链表l中第n次出现的位置,如果没有第n次,返回0,有返回位置 int list_find_value_location(list l,unsigned int n,TYPE value) { int i,count =0; for(i=0;l.length;i++) { if(value == l.head->value) { if(n == ++count)return i+1; } } return 0; } //得到链表l中第loc个位置的值,为零时候提示出错,将结果写到result中 int list_get_value(list l,unsigned int loc,TYPE * result) { int i; if(0==loc) {return CROSSBORDER;} for(i=0;i<loc-1;i++) { l.head = l.head->next; } *result = l.head->value; return 0; } //删除链表l中第loc个节点,后面的节点补上。 int list_delete(list *l,int loc) { int i; ptrlnode tmpnode = NULL; ptrlnode freenode =NULL; tmpnode = l->head; if(0>=loc || loc >l->length) { printf("cross-border!\n"); return CROSSBORDER; } else if(1==loc) { freenode =l->head; l->head = (l->head)->next; } else { for(i=1;i<loc-1;i++) { tmpnode = tmpnode->next; } freenode =tmpnode->next; if(freenode) tmpnode->next =freenode->next; else tmpnode->next = NULL; } free(freenode); l->length --; return 0; } //删除链表l中第一个值是value值的节点 2012-07-30 int list_delete_first(list *l,TYPE value) { int i; ptrlnode tmpnode = NULL; ptrlnode freenode =NULL; tmpnode = l->head->next; if(value == l->head->value) { freenode = l->head;l->head = tmpnode;} else { for(i=1;i<l->length-1;i++) { tmpnode = tmpnode->next; } freenode =tmpnode->next; if(freenode) tmpnode->next =freenode->next; else tmpnode->next = NULL; } free(freenode); l->length --; return 0; } //打印链表 void list_print(list l) { char *str; char *p; int i; if(1 !=sizeof(TYPE)) { ptrlnode node = l.head; while(node) { printf(FORMAT,node->value ); node = node ->next; } } else { str = (char *) malloc(sizeof(char)*l.length); if(NULL != str) { for(i=0;i<l.length;i++) { str[i]=l.head->value; l.head = l.head->next; } } } printf("%s\n",str); } //链表逆转 //原理:源:head -> 1 -> 2 ->3 -> 4 -> null; //第一步: null <- 1 <- 2 , 3 ->4 - null; //第二步: null <- 1 <- 2 <- 3, 4 - null; //第三步: null <- 1 <- 2 <- 3 <- 5; //最后一步: head -> 5; void list_reverse(list *l) { int length = l->length; int i; ptrlnode tmphead = NULL; ptrlnode node ; ptrlnode head = l->head; for(i =0;i<l->length;i++) { node = head; head = head ->next; node->next = tmphead ; tmphead = node ; } l->head = tmphead ; } //将源链表中source拷贝到链表dest中的,但是主要我没有释放dest原有的空间, //学要保证dest本身为空,source与dest并没有共享空间。 void list_copy(list source,list * dest) { ptrlnode snode = source.head; ptrlnode dest_node,tmpnode ; if(snode) { dest->head = dest_node=tmpnode = (ptrlnode )malloc(sizeof(lnode)); if(NULL == tmpnode){printf("Failed to allocate memory!\n");exit(0);} tmpnode->value = snode->value; snode=snode->next; while(snode) { tmpnode = (ptrlnode )malloc(sizeof(lnode)); if(NULL == tmpnode){printf("Failed to allocate memory!\n");exit(0);} tmpnode ->value = snode->value ; dest_node ->next= tmpnode; dest_node = tmpnode ; snode = snode ->next; } } dest->length=source.length; } //复制链表source中的从start开始的len元素到链表result中,如果len多于剩下的元素, //复制余下所有的元素 int list_sub(list *source,list *result,int start ,int len) { //源链表的节点,用于分配空间的节点,目标链表的前一个节点 ptrlnode source_node,tmp_node,result_previous; int i; if(0>=start || start > source->length){printf("start is error \n");return CROSSBORDER;} if(len >(source->length-start))len = source ->length -start+1; source_node = source->head; //找到第一个需要复制的节点 for(i=1;i<start;i++) { source_node=source_node->next; } //复制节点 result->head=result_previous = tmp_node=(ptrlnode) malloc(sizeof(lnode)); if(NULL == tmp_node){print_memory_fail();exit(0);} tmp_node->value = source_node->value; source_node =source_node->next; for(i=1;i<len;i++) { tmp_node=(ptrlnode) malloc(sizeof(ptrlnode)); if(NULL == tmp_node){print_memory_fail();exit(0);} tmp_node->value = source_node->value; source_node =source_node->next; result_previous->next = tmp_node; result_previous =tmp_node; } result->length =len; return 0; } //将链表l的元素合并到链表result后面。 int list_merger_tail(list l,list *result) { ptrlnode tmp_node ,result_previous; int i; if(0==l.length)return 0; result_previous = result->head; for(i=1;i<result->length;i++) result_previous = result_previous->next; for(i=0;i<l.length;i++) { tmp_node =(ptrlnode)malloc(sizeof(lnode)); if(NULL == tmp_node){print_memory_fail();exit(0);} tmp_node->value =l.head->value ; result_previous->next = tmp_node; result_previous=tmp_node; l.head = l.head->next; } result->length +=l.length; return 0 ; } //销毁链表l,释放空间 void list_destory(list * l) { ptrlnode free_node ; while(l->head) { free_node=l->head; l->head=(l->head)->next; free(free_node); } l->length=0; }
相关文章推荐
- 数据结构学习(三)——单链表的操作之查找、删除、插入。
- [数据结构学习]单链表常用操作
- 数据结构学习(二)——单链表的操作之头插法和尾插法创建链表
- 数据结构学习(二)——单链表的操作之头插法和尾插法创建链表
- 数据结构学习(二)——单链表的操作之头插法和尾插法创建链表
- 数据结构学习笔记(二) 链表之单链表的基本操作
- 数据结构学习之单链表
- 笔试面试常考数据结构-单链表常用操作编程实现
- 数据结构学习笔记(二) 链表之链队列基本操作
- 数据结构基础之单链表基本操作实现
- 数据结构学习(五)——循环双链表的操作之创建,插入、删除
- 数据结构学习1:链表的相关操作
- 工大数据结构之实验指导之【一】单链表的操作
- 【C++/数据结构】单链表的基本操作
- 数据结构学习笔记(二) 链表之带表头结点的单循环链表基本操作
- 算法数据结构 单链表的实现+操作 以及和顺序表的对比
- C数据结构 单链表操作
- 数据结构学习问题笔记之单链表
- 快速学习单链表的创建和操作(包含程序和程序注解)
- 数据结构学习——单链表ADT(程序化)