1. 程式人生 > >連結串列(C語言)

連結串列(C語言)

1、連結串列的定義

typedef struct stu
{
	int num;
	struct stu *next;
}stu,*student;

2、連結串列的建立

        連結串列是用指標連線起來的線性表,對於連結串列的每個結點,都要給它動態分配記憶體,這點很重要,不然程式會崩潰。

        遞迴方式:每輸入一個數就在連結串列尾連線上一個結點。

student create_1()//遞迴方式建立連結串列 
{
	student T;
	int a;
	scanf("%d",&a);
	if(a!=0)
	{
		T=(student)malloc(sizeof(stu));
		T->num=a;
		T->next=create_1();
		return T;
	}
	return NULL;
}

        非遞迴方式:用陣列的方式,陣列中每個元素都是連結串列的一個結點,通過遍歷陣列,來將連結串列連線起來。

student create_2(int n)//非遞迴方式建立連結串列 
{
    int i;
	student pArr[n];
	for(i=0;i<n;i++)
	{
		pArr[i]=(student)malloc(sizeof(stu));
		pArr[i]->num=i+1;
	}
	for(i=0;i<n-1;i++)
		pArr[i]->next=pArr[i+1];
	pArr[i]->next=NULL;//若尾結點指向空,則這是單鏈表,若指向頭結點,則這是迴圈連結串列,長度就是陣列長度。
	return pArr[0];
}

        建立迴圈連結串列:上一中非遞迴方式也可以建立迴圈連結串列,這是第二種方式。

student create_3(int n)//建立長度為n的迴圈連結串列 
{
	student ptail,phead,p;
	phead=(student)malloc(sizeof(stu));
	phead->num=1;
	phead->next=phead;
	p=phead;
	for(i=1;i<n;i++)
	{
		ptail=(student)malloc(sizeof(stu));
		ptail->num=i+1;
		ptail->next=phead;
		p->next=ptail;
		p=ptail;
	}
	return phead;
}

3、連結串列的操作

        刪除一個元素:實現原理是將該元素的前一個結點指向該結點的後一個結點,這樣再連結串列遍歷時,就跳過了這個結點。再將要刪除這個結點的記憶體清空。

void Delete(student head,int d)//刪除指定元素 
{
	student p=head,temp=head->next;
	while(temp->next!=NULL)
	{
		if(temp->num==d)
		{
			p->next=temp->next;
			free(temp);
			return;
		}
		else
		{
			temp=temp->next;
			p=p->next;
		}
	}
}

        插入一個元素:為新插入的結點分配記憶體,而且插入位置的原結點要指向新結點,新結點指向原結點的後一個結點。

void Insert(student pArr[],int element,int position)//插入一個元素到指定位置 
{
	student New=(student)malloc(sizeof(stu));//為新插入的結點分配記憶體很重要。 
	New->num=element;
	New->next=pArr[position];
	pArr[position-1]->next=New;
}

4、連結串列的反序

        使用棧結構:先從前往後逐個壓入棧,再從後往前逐個出棧。

student resever_1(student head)//用棧實現連結串列的反序 
{
	int top=-1;//-1時表示棧內沒有元素
	student stack[100];
	while(head->next!=NULL)
	{
		stack[++top]=head;
		head=head->next;
	}
	student temp=head;
	while(top>=0)
	{
		head->next=stack[top];
		head=stack[top];
		top--;
	}
	head->next=NULL;
	return temp;//temp為反序後的新連結串列的頭結點
}

        不使用多餘空間,原地反序:

student resever_2(student head)//連結串列的原地反序 
{
	student p,p1=NULL,p2=head;
	while(p2!=NULL)
	{
		p=p2->next;
		p2->next=p1;
		p1=p2;
		p2=p;
	}
	return p1;
}

        值的注意的是,連結串列是單向性的,且指標一次只能移動一個位置,所以在連結串列的操作中總是需要定義兩到三個結構體指標,才足夠完成操作。