纯c语言实现链表,实现链表增删改查

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct selflist{
   int num;
   selflist* next;
};

struct selflist* head = NULL;

//根据大小创建链表
void init(int size){
    struct selflist* tmp = NULL;
	struct selflist* tail = NULL;
	head = (struct selflist*) malloc(sizeof(struct selflist));
	if(NULL==head){
	  printf("初始化链表头失败\n");
	  return;
	}
	head->next = NULL;
	tmp = head;
	for(int i = 0; i < size-1; i++){
	
		tmp->num = i;//rand();
		tmp->next = NULL;
		tail = tmp;
		tmp = tmp->next;
		tmp = (struct selflist*) malloc(sizeof(struct selflist));
		if(NULL==tmp){
	        printf("初始化临时链表失败\n");
	        return;
		}
		tail->next = tmp;
	}  
	///最后一个无须在malloc空间
	tail->next->num = size-1;
	tail->next->next = NULL;

}
//释放链表的每个节点
void FreeList(){
    if(NULL==head) return;
	struct selflist* tmp = head->next;
	while(head){
	    free(head);
		head=NULL;
		if(tmp){

		head = tmp;
		tmp = tmp->next;
		}
	}
}
//末尾插入元素
void insert(int num){

   struct selflist* tmp = head;
   while(tmp){
	   if(NULL == tmp->next){
		     struct selflist*  insert = (struct selflist*) malloc(sizeof(struct selflist));
             if(insert){
				 insert->num = num;
				 insert->next = NULL;
	             tmp->next = insert;
             }else{
               printf("加入数据失败\n");
             }
			 return;
	   }
	   tmp = tmp->next;
   }
  
}
//指定位置加入数据
void insert_ex(int num, int pos){
   //pos从0开始,如pos=0,则表示在head前加入一个元素
	int size=0;
	struct selflist* tmp = head;//临时复制head,对tmp操作只是不会影响head仍然指向头
	while(tmp){
	   ++size;
	   tmp = tmp->next;
	}
	if(pos<0 || pos>=size) {//加入链表末尾
	  insert(num);
	}else{
	   size = 0;
	   struct selflist*  insert = (struct selflist*) malloc(sizeof(struct selflist));
	   if(!insert){
		   printf("指定位置加入元素失败\n");
		   return;
	   }
	   insert->num = num;
	   insert->next = head;
	   if(pos==size){
		   head = insert;
		   return;
	   }
	   tmp = head;
	   struct selflist* p = NULL;
	   while(tmp){
		   if(pos-1==size){
			   p = tmp->next;
			   tmp->next = insert;
			   insert->next = p;
			   return;
		   }
		   tmp = tmp->next;
		   ++size;
	   }
	}
}

//删除指定位置元素
void deletelist(int pos){
	if(NULL==head) return;
	if(pos==0){
	  struct selflist* p = head;
	  struct selflist* t = head->next;
      free(p);
	  p=NULL;
	  head = t;
	  return;
	}
	int size=0;
	struct selflist* tmp = head;
	while(tmp){
	   ++size;
	   tmp = tmp->next;
	}
	if(pos<0 || pos>=size){//删除末尾
      pos = size-1;
	}
	tmp = head;
	size = 0;
	while(tmp){
		if(pos-1==size){
			struct selflist* p = tmp->next->next;
			free(tmp->next);
			tmp->next = NULL;
			tmp->next  = p;
			return;
		
		}
		tmp = tmp->next;
		++size;
	}
}

//删除指定元素
void deletenum(int num, bool flag){
  //flag:true//删除所有为num的元素
  //flag:false//只删除找到第一个num的元素
  if(NULL==head) return;
  struct selflist* tmp = head;
  int size=0;
  while(tmp){
	  ++size;
	  if(tmp->num == num){
	      deletelist(size-1);
		  tmp = tmp->next;
		  if(flag) continue;
		  else break;
	  }
	  tmp = tmp->next;
  }

}
/*
  位置从0开始
  flag:true://找所有num
  flag:false;//找第一个num
*/
void findnum(int num, bool flag){
    if(NULL==head) return;
	struct selflist* tmp = head;
	int size = 0;
	while(tmp){
		if(tmp->num == num){
		  printf("找到%d元素,位于链表第%d位置\n",num,size);
		  tmp = tmp->next;
		  if(flag) continue;
		  else break;
		}
		tmp = tmp->next;
		++size;
	}
	
}
//打印链表
void Print(){
	struct selflist* tmp = head;
	while(tmp){
	   
		printf("%d\n",tmp->num);
        tmp = tmp->next;
	}

}

//链表倒序
void reverse(){
    if(NULL==head) return;
	struct selflist* s = NULL;
	struct selflist* t = head->next;//保存当前链表地址,head的改变不会影响此时的t,但t的改变会影响head
	
	while(head){
		head->next = s;//指向前一个节点
		s = head;//前一个节点,这个head为前面的head->next的head即新的链表
		head = t;//下一个节点,这个head为原来的head只是变为head->next即原来的链表
		if(NULL==t) break;//说明是最后一个节点了。
		if(head){
		  t = head->next;//得到下一个节点
		}
	    
	}
	head = s;
}

猜你喜欢

转载自blog.csdn.net/abqchina/article/details/53994136