1. 程式人生 > >C語言實現連結串列、棧、佇列的基本操作

C語言實現連結串列、棧、佇列的基本操作

一、連結串列的基本操作

#include <stdio.h>
#include <stdlib.h>
typedef struct LNode{
	int data;
	struct LNode *next;
}LNode,*LinkList;
//頭插法 
LinkList create_list_head(int n){ 
     LinkList head = (LinkList)malloc(sizeof(LinkList)); //分配帶有表頭結點的單鏈線性表 
     head->next = NULL;   //建立一個帶頭結點的單鏈表 
     int i;
     for(i=n;i>0;i--){
     	LinkList p = (LinkList)malloc(sizeof(LinkList));  //生成新的結點
		scanf("%d",&(p->data));  //將輸入的資料存入資料域中 
		p->next = head->next;    
		head->next = p;             //插入到表頭中 
     }
  return head;
}
//尾插法 
LinkList create_list_tail(int n){
	LinkList head = (LinkList)malloc(sizeof(LinkList)); //分配帶有表頭結點的單鏈線性表 
     head->next = NULL;   //建立一個帶頭結點的單鏈表 
     int i;
     LinkList tail;       
     for(i=n;i>0;i--){
   	  LinkList p = (LinkList)malloc(sizeof(LinkList));  //生成新的結點
		scanf("%d",&(p->data));  //將輸入的資料存入資料域中 
        if(head->next == NULL){  //插入頭結點的第一個元素 
        	head->next = p;
        	tail = p; 
        }else{                   //插入後面的元素 
        	tail -> next = p;
            tail = p;
        } 
     }
     tail -> next = NULL;
  return head;
}

//元素節點總長度,個數不包括頭結點  
int total_length(LinkList head){
	LinkList p = head->next;
	int count = 0;
	while(p){
		count++;
		p = p->next;
	}
	return count;
}
//獲取第i個元素 ,個數包括頭結點 
int get_element(LinkList head,int i,int *element){
	LinkList p = head -> next;
	int j = 0;
	while(p && j<i){
		p = p->next; ++j;
	}
	if(!p || j>i) return 0;
	*element = p->data;
	return 1;
}

//查詢第一個值為element的元素,返回下標 
int location_element(LinkList head,int element){
	LinkList p = head -> next;
	int i = 1;
	while(p && p->data!=element){
	    p = p->next;
	    i++;
	}
	if(!p) return 0;
	return i;
}
//在帶有頭結點的單鏈表中第i個位置之前插入元素element ,個數不包括頭結點 
int list_insert(LinkList head,int i,int element){
   LinkList p = head -> next;
   int j = 1;
   while(p && j<i-1){
   	  p = p->next; 
   	  j++;
   }
   if(p->next==NULL || j>i) return 0;
   LinkList newp = (LinkList)malloc(sizeof(LinkList));
   newp -> data = element;
   newp -> next = p->next;
   p->next = newp;
   return 1;
}

//刪除第i個元素,並由element返回刪除的值 ,個數不包括頭結點 
int list_delete(LinkList head,int i,int *element){
	LinkList p = head -> next;
	int j = 1;
	while(p && j<i-1) {
		p = p->next;
		j++;
	}
	if(p->next==NULL || j>i) return 0;
	LinkList q = p -> next;
	*element = q -> data; 
	p->next =  q -> next;
	free(q);
	return 1;
}

//已知第一個和第二個單鏈線性表的元素是按照值進行非遞減排列,歸併後新的單鏈表也按照值進行非遞減排列 
LinkList list_merge(LinkList head1,LinkList head2){
	LinkList pa = head1 -> next; 
	LinkList pb = head2 -> next;
	LinkList pc,head3;
	head3 = pc = head1;   //用第一個連結串列的頭結點作為lc的頭結點 
	while(pa && pb){
		if(pa -> data <= pb -> data){
			pc -> next = pa;
			pc = pa;
			pa = pa -> next;
		}else{
			pc -> next = pb;
			pc = pb;
			pb = pb -> next;
		}
		pc -> next = pa?pa:pb; //插入剩餘段 
		free(head2);  //釋放第二個連結串列的頭結點 
	}
	return head3;
}

void print(LinkList head){ 
    printf("數字連結串列內容為:\n"); 
	LinkList p = head->next; 
    while(p){
    	printf("%d ",p->data);
    	p = p->next;
    }
}
int main(){
	int n1,n2;
	LinkList head;
	scanf("%d",&n1);
	head = create_list_head(n1);
	//print(head);

	//print(head1);
	//printf("%d",total_length(head));
	//int element;
	//if(get_element(head,2,&element)){
	//    printf("%d",element);
	//}else{
	//	printf("不存在");
	//}
	int element;
	scanf("%d",&element);
	int location = location_element(head,element);
	if(location){
	   printf("位置為:%d",location);
	}
	//if(list_insert(head,3,9)){
	//		print(head);
	//}else{
    //	printf("不存在");	
	//}
	//int element1;
	//if(list_delete(head,4,&element1)){
	//	printf("刪除的元素為:%d",element1);
	//	print(head);
	//}else{
	//	printf("刪除失敗");
	//}
	//scanf("%d",&n2);
	//LinkList head1 = create_list_tail(n2);
	//LinkList head3 = list_merge(head,head1);
	//print(head3);
	return 0;
}

二、棧的基本操作

#include <stdio.h>
#include <stdlib.h>
#define STACKINCREMENT 10
typedef struct{
	int *base;
	int *top;
	int stacksize;
}SqStack;

//初始化棧 
int init_stack(SqStack &s,int n){
	s.base = (int *)malloc(sizeof(int));
	if(!s.base) return 0;
	s.top = s.base;
    s.stacksize = n;
    return 1;
}
//判斷棧是否為空 
int empty_stack(SqStack s){
	if(s.top==s.base){
		return 1;
	}
	return 0;
}
//壓棧 
int push_stack(SqStack &s,int e){
	 if (s.top - s.base >= s.stacksize)  {  
        s.base = (int *)realloc(s.base, (s.stacksize + STACKINCREMENT) * sizeof(int));  
        if(!s.base) return 0;
        s.top = s.base + s.stacksize;//棧底地址可能改變,重新定位棧頂元素  
        s.stacksize = s.stacksize + STACKINCREMENT;  
    }  
    *s.top = e;  
    s.top++; 
    return 1; 
}

//出棧
int pop_stack(SqStack &s,int *element) {
	if(empty_stack(s)) return 0;
     *element = *(s.top-1);
     s.top--;
    return 1;
}
//查詢棧頂元素 
bool get_top(SqStack s,int *element){
   if(s.base == s.top) return false;	
   *element = *(s.top-1);
   return true;
}

//查詢棧的長度
int get_length(SqStack s){
	int length = 0;
	while(s.top	!= s.base){
           length++;
           s.top--;
	}
	return length;
} 
int main(){
   SqStack s;
   int n;
   printf("輸入棧大小:");
   scanf("%d",&n);
   init_stack(s,n);
   int i;
   for(i=1;i<=n;i++){
     printf("輸入棧的第%d個元素\n",i);
     int e;
     scanf("%d",&e);
     push_stack(s,e); 
   }
   int element;
   if(get_top(s,&element)){
   	   printf("棧頂元素為:%d\n",element);
   }
   printf("棧的長度為:%d\n",get_length(s));
   int top_e;
   if(pop_stack(s,&top_e)){
   	   printf("pop棧頂元素:%d\n",top_e);
   }
   printf("pop元素後棧的長度為:%d\n",get_length(s));
}

三、佇列的基本操作

經過本人樣例測試,可能還有未完善的地方,有錯誤的地方希望批評指正!!