1. 程式人生 > >C語言線性單鏈表相關函式和演算法的基本實現

C語言線性單鏈表相關函式和演算法的基本實現

備考期間嘗試寫了一些基本資料結構的C語言實現,現做以下記錄(基本資料元以int型為例):

全域性定義及依賴:

#include <stdio.h> 
#include <stdlib.h>
#define OK  1
#define ERROR  0
#define END NULL

連結串列結點定義:

typedef struct Lnode
{
	int data;
	struct Lnode *next;
}Node,*linkedList;

連結串列初始化:

//初始化連結串列 
linkedList initList()
{
	Node *L;
	L = (Node *)malloc(sizeof(Node));
	if(L==NULL)
	{
		printf("Init error!");
	}
	L->next = NULL;
	printf("Init OK!\n");
	return L;
}
頭插法生成連結串列 即在頭結點後插入新元素 :
//頭插法生成連結串列 即在頭結點後插入新元素 
linkedList createListH(int n)
{
	int i = 0;
	Node *L;
	L = (Node *)malloc(sizeof(Node));
	L->next = NULL;
	
	int x;
	while(i<n)
	{
		scanf("%d",&x);
		Node *p;
		p = (Node *)malloc(sizeof(Node));
		p->data = x;
		p->next = L->next;
		L->next = p;
		i++;
	}
	return L;
}
尾插法生成連結串列 即在尾結點後插入新元素:
//尾插法生成連結串列 即在尾結點後插入新元素
linkedList createListT(int n)
{
	int i = 0;
	Node *T;
	T = (Node *)malloc(sizeof(Node));
	T->next = NULL;
	
	Node *r;
	r = T;
	int x;
	while(i<n)
	{
		scanf("%d",&x);
		Node *p;
		p = (Node *)malloc(sizeof(Node));
		p->data = x;
		r->next = p;
		r = p;
		i++;
	}
	r->next = NULL;
	return T;
}

計算連結串列長度:

//calculate the length
int calculateLength(linkedList L)
{
	int length = 0;
	Node *p = L;
	while(p->next)
	{
		length++;
		p = p->next;
	}
	return length;
} 

在指定連結串列的指定索引處插入新值:

//insert element into index x
int insertElementIntoX(linkedList L,int index,int e)
{
	Node *p = L;
	int length = calculateLength(L);

	if(index<1||index>length+1){return ERROR;}
	else
	{
		for(int i = 1;i<index;i++)
		{
			p = p->next;
		}
		Node *q = (Node *)malloc(sizeof(Node));
		q->data = e;
		q->next = p->next;
		p->next = q;
		return OK;
	}
}

通過索引刪除指定連結串列中的元素:

//delete element by index
int deleteElementByIndex(linkedList L,int index)
{
	int length = calculateLength(L);
	if(index<1||index>length){return ERROR;}
	else
	{
		Node *p = L;
		for(int i = 1;i<index;i++)
		{
			p = p->next;
		}
		Node *q = p->next;
		p->next = q->next;
		free(q);
		return OK;
	}
}

遍歷並列印連結串列中所有結點元素:

//遍歷 
void traversalList(linkedList L)
{
	Node *p = L->next;
	while(p!=END)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
}

對兩個連結串列做非遞減歸併:

linkedList mergeDecline(linkedList La,linkedList Lb)
{
	Node *a = La->next;
	Node *b = Lb->next;
	free(La);
	free(Lb);
	linkedList Lc = initList();
	Node *temp = Lc;
	while(a!=NULL&&b!=NULL)
	{
		if(a->data<=b->data)
		{
			temp->next = a;
			a = a->next;
			temp = temp->next; 
		}
		else
		{
			temp->next = b;
			b = b->next;
			temp = temp->next;
		}
	}
	temp->next == NULL;
	if(a!=NULL){temp->next = a;}
	if(b!=NULL){temp->next = b;}
	return Lc;
}

刪除給定連結串列中所有重複元素(對重複元素只保留其中一個):

//delete repeating node  
void deleteRepeatingNode(linkedList L)
{
	Node *p,*q,*r;
	p = L->next;
	if(p==NULL){return;}
	while(p->next)
	{
		q = p;
		while(q->next)
		{
			if(q->next->data==p->data)
			{
				r = q->next;
				q->next=r->next;
				free(r);
			}
			else
			{
				q = q->next;
			}
		}
		p = p->next;
	}
}

將連結串列中的元素按從小到大進行排序:

//sort from small to large
int sortFSL(linkedList L)
{
	if(L->next==NULL){return ERROR;}
	else
	{
		Node *r = L;
		Node *p = r->next;
		Node *q = p->next;
		while(p->next)
		{
			while(q)
		    {
			  if(p->data>q->data)
			  {
				   int e = p->data;
				   p->data = q->data;
				   q->data = e;
				   q = q->next;
			  }
			
			  else
			  {
				  q = q->next;
			  }
		    }
		    
		    r = r->next;
		    p = p->next;
		    q = p->next;
		}
		return OK;
	}
	
}

刪除連結串列中所有元素值大於x的結點:

int deleteAGTX(linkedList L,int x) 
{
	if(L->next==NULL){return ERROR;}
	else{
		Node *p = L;
		while(p->next)
		{
			if(p->next->data>x)
			{
				Node *temp = p->next;
				p->next = p->next->next;
				free(temp);
			}
			else{
				p = p->next;
			}
		}
		return OK;
	}
}

將連結串列中所有負數前置並排序:

//負數在前排序 
int negativePriority(linkedList L)
{
	if(L->next==NULL){return ERROR;}
	else{
		Node *p = L;
		while(p->next)
		{
			if(p->next->data<0)
		    {
			  Node *temp = p->next;
			  p->next = temp->next;
			  temp->next = L->next;
			  L->next = temp;
		    }
		    else{p = p->next;}
		}
		return OK;
	}
} 

南京航空航天大學922部分真題:

//2014真題-資料結構6
int _2014_T6(linkedList L)
{
	if(L->next==NULL){return ERROR; }
	else{
		Node *p = L;
		Node *t = NULL;
		Node *s = NULL;
		int count = 1;
		while(p->next)
		{
			if(count%2==0)
			{
				t = p->next;
				p->next = p->next->next; //關鍵步驟 
				t->next = s;
				s = t;
			}
			else{
				p = p->next;
			}
			count++;
		}
		p->next = s;
		return OK;
	}
} 

//2015真題資料結構6
int _2015_T6(linkedList L)
{
	if(L->next==NULL){return ERROR; }
	else{
		Node *p = L->next;
		Node *q = L->next;
		Node *t = L;
		Node *top = NULL;
		while(p->next)
		{
			while(q->next)
			{
				if(q->next->data>p->data)
				{
					p = q->next;
					t = q;
					q = q->next;
				}
				else{
					q = q->next;
				}
			}
			t->next = t->next->next;
			p->next = top;
			top = p;
			t = L;
			p = q = L->next;
		}
		p->next = top;
		return OK;
	}
} 

//2013真題資料結構6
int _2013_T6(linkedList La,linkedList Lb)
{
	if(La->next==NULL){return ERROR;}
	else{
		Node *a = La;
		Node *b = Lb;
		int element;
		while(a->next)
		{
			element = a->next->data;
			while(b->next)
			{
				if(b->next->data==element){break;}
				else{b = b->next;}
			}
			
			if(b->next==NULL)
			{
				Node *t = a->next;
				a->next = a->next->next;
				free(t);
			}
			else{a = a->next;} 
			b = Lb;
		}
		
		a = La;
		while(a->next)
		{
			Node *p = La->next;
			int e;
			while(p->next)
			{
				if(p->next->data>a->next->data)
				{
					e = a->next->data;
					a->next->data = p->next->data;
					p->next->data = e;
				}
				p = p->next;	
			}
			a = a->next;
		}
		return OK;
	}
}

//2011真題-資料結構24
int _2011_T24(linkedList L)
{
    if(L->next == NULL){return ERROR;}
    else{
    		Node *p = L;
	        int element = p->next->data;
	        while(p->next)
	        {
		       if(element>p->next->data)
		       {
			      element = p->next->data;
		       }
		       p = p->next;
	        }
	        p = L;
	        while(p->next)
	        {
	        	if(p->next->data==element)
	        	{
	        		Node *t = p->next;
	        		p->next = p->next->next;
	        		free(t);
	        		break;
	        	}
	        	p = p->next;
	        }
	        return OK;
    }
}

使用單鏈表實現數制轉換(1-10進位制):

//數制轉換(1-10進位制)
void transCodeR(int num,int r)
{
	linkedList L = initList();
	L->data = -1;
	Node *top = NULL;
	int i;
	while(num>0)
	{
		i = num%r;
		top = (Node *)malloc(sizeof(Node));
		top->data = i;
		top->next = L;
		L = top;
		num = num/r;
	}
	printf("The result is: ");
	while(top->data!=-1)
	{
		printf("%d ",top->data);
		top = top->next;
	}	
} 

測試:

int main()
{
	int n = 0;
	
	printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList La = createListT(n);
	printf("Traversal the list a:\n");
	traversalList(La);
	
	printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Lb = createListT(n);
	printf("Traversal the list b:\n");
	traversalList(Lb);

    traversalList(mergeDecline(La,Lb)); //Merge
    
    printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Ld = createListT(n);
	traversalList(Ld);
    deleteRepeatingNode(Ld);  //delete repeating node
    traversalList(Ld);
    
    int index,element;
    printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Le = createListT(n);
	traversalList(Le);
	printf("Please enter the index:\n");
	scanf("%d",&index);
	printf("Please enter the element:\n");
	scanf("%d",&element);
	insertElementIntoX(Le,index,element);  //insert element into index x
	traversalList(Le);
	
	int index;
	printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Lf = createListT(n);
	traversalList(Lf);
	printf("Please enter the index:\n");
	scanf("%d",&index);
	deleteElementByIndex(Lf,index);  //delete element by index
	traversalList(Lf);
	
    printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Lg = createListT(n);
	traversalList(Lg);
	sortFSL(Lg);         //sort from small to large
	traversalList(Lg);
    
    int x;
    printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Lh = createListT(n);
	traversalList(Lh);
	printf("Please enter the value:\n");
	scanf("%d",&x);
	deleteAGTX(Lh,x);         //P3-3-2-3-1 刪除所有元素值大於x的結點
	traversalList(Lh);
	
    printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Li = createListT(n);
	traversalList(Li);
	negativePriority(Li);         //負數在前排序
	traversalList(Li);
	
	printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Lj = createListT(n);
	traversalList(Lj);
	_2014_T6(Lj);         //2014真題-資料結構6
	traversalList(Lj);
	
	printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Lk = createListT(n);
	traversalList(Lk);
	_2015_T6(Lk);         //2015真題-資料結構6
	traversalList(Lk);
	
	printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Ll = createListT(n);
	traversalList(Ll);
	printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Lm = createListT(n);
	traversalList(Lm);
	_2013_T6(Ll,Lm);         //2013真題-資料結構6
	traversalList(Ll);
	
    printf("Please enter the length:\n");
	scanf("%d",&n);
	linkedList Ln = createListT(n);
	traversalList(Ln);
	_2011_T24(Ln);
	traversalList(Ln);  //2011真題-資料結構24
	
	int num;
	printf("Please enter the num:\n");
	scanf("%d",&num);
	printf("Please enter the r:\n");
	scanf("%d",&n);
	transCodeR(num,n);
	
	return 0;
}