1. 程式人生 > >純c語言實現連結串列,實現連結串列增刪改查

純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;
}