標籤:blog os io 檔案 for 2014 ar cti
以下都是單鏈表的基本操作,我都寫了一遍,鏈表時間長不寫一定會陌生,留給自己以後忘了看一眼,順便給想學習鏈表的同學一點提示吧
首先先寫標頭檔head.h,這裡都是我定義好的函數分別有
這裡的所有例子都是有頭結點的鏈表,都是單鏈表操作
1)頭插發建表 2)尾插法建表 3)列印鏈表 4)對鏈表賦值的時候進行插入排序 5)將鏈表翻轉 6)找到鏈表倒數第n個元素 7)將兩個鏈表連在一起 8)使單鏈表變成環鏈表
9)判斷鏈表是否有環 10)將現有的鏈表排序進行插入排序(與4)不同,4)是在建立鏈表的時候進行排序,) 11)刪除鏈表重複元素 12)判斷鏈表是否有交點,並輸出 13)使兩個鏈表有交點
#ifndef _LINK_H_#define _LINK_H_#include<iostream>#include<stdio.h>#include<time.h>#define outusing namespace std;struct node_stu{int num;node_stu *next;};void link_init_tail(node_stu **head,int size);void link_init_head(node_stu **head,int size);void print_link(node_stu *head);void link_init_sort_insert(node_stu **head,int size);void turn_link(node_stu **head);int find_back_num(node_stu *head,int n);int find_back_num(node_stu *head);void unite_links(node_stu **head1,node_stu **head2);void make_link_into_circle(node_stu **head);int judge_circle(node_stu *head);void sort_link(node_stu **head);void delete_repetition(node_stu** head);int count_intersection(node_stu *head1,node_stu *head2,node_stu** node_intersection);void make_intersection_link(node_stu** head1,node_stu** head2,int ,int );#endif
1)頭插發建表
#include"head.h"void link_init_head(node_stu **head,int size){*head=(node_stu*)calloc(1,sizeof(node_stu));node_stu *p=*head;p->next=NULL;for(int i=0;i<size;i++){node_stu *temp=(node_stu*)calloc(1,sizeof(node_stu));temp->num=rand()%100;;temp->next=p->next;p->next=temp;}}
2)尾插法建表
#include"head.h"void link_init(node_stu **head,int size){node_stu *p;*head=(node_stu *)calloc(1,sizeof(node_stu));p=*head;p->next=NULL;for(int i=0;i<size;i++){p->next=(node_stu *)calloc(1,sizeof(node_stu));p=p->next;p->num=rand()%100;p->next=NULL;}}
3)列印鏈表
#include"head.h"void print_link(node_stu* head){while(head->next!=NULL){head=head->next;cout<<head->num<<" ";}cout<<endl;}
4)對鏈表賦值的時候進行插入排序
<pre class="cpp" name="code">#include"head.h"void link_init_sort_insert(node_stu **head,int size){*head=(node_stu*)calloc(1,sizeof(node_stu));//定義頭指標node_stu *p=*head,*pre=*head;//定義指標p和前指標pre(*head)->next=NULL;//初始化頭指標(*head)->num=-1;for(int i=0;i<size;i++){p=*head;node_stu *temp=(node_stu*)calloc(1,sizeof(node_stu));temp->num=rand()%100;//定義節點並且賦予隨機數cout<<temp->num<<" ";temp->next=NULL;pre=p;int flag_mid=0;//標記在中間進行插入while(p->next!=NULL){pre=p;p=p->next;//p在前面探路,pre緊隨其後,然後temp找到合適位置就插在pre和p適當的位置if((temp->num)>=(pre->num) && (temp->num)<=(p->num)){flag_mid=1;break;}}if(flag_mid!=1)//在頭插入或者在未插入p->next=temp;else {pre->next=temp;//在pre和p中間插入temp->next=p;}}}
5)將鏈表翻轉
#include"head.h"void turn_link(node_stu **head){//node_stu *newhead=(node_stu*)calloc(1,sizeof(node_stu));//newhead->next=NULL;將鏈表逆序node_stu *p=*head;p=p->next;(*head)->next=NULL;while(p!=0){node_stu *temp=(node_stu*)calloc(1,sizeof(node_stu));//定義一個臨時結構體節點temp=p;p=p->next;temp->next=NULL;//從鏈表頭部中截取一個節點temp->next=(*head)->next;//將這個節點(頭插法)插到表頭中(*head)->next=temp;}}
6)找到鏈表第n個元素
#include"head.h"int find_back_num(node_stu *head,int n){node_stu *pre;pre=head;//至樓頂兩個指標,一個head一個pre,中間間隔nn--;while(n--)pre=pre->next;while(pre->next!=NULL){//當pre到頭的時候head就是倒數第n個pre=pre->next;head=head->next;}return head->num;}
7)將兩個鏈表串連在一起
<pre class="cpp" name="code">#include"head.h"void unite_links(node_stu **head1,node_stu **head2){//將兩個鏈表結合node_stu *p;p=(*head1);while(p->next!=NULL)p=p->next;p->next=(*head2)->next;//delete (node_stu*) head2;}
8)將鏈表變成迴圈鏈表
<pre class="cpp" name="code">#include"head.h"void make_link_into_circle(node_stu **head){//是head鏈表變成有環的node_stu *p;p=(*head);while(p->next!=NULL)p=p->next;p->next=(*head)->next;}
9)判斷鏈表是否有環
<pre class="cpp" name="code">#include"head.h"int judge_circle(node_stu *head){node_stu *p;p=head->next;head=head->next;while(head!=NULL){head=head->next;if(head==p)return 1;}return 0;}
10)將鏈表進行插入排序
主要思想是,將鏈表的一個點摘下來,在用原鏈表的頭作為新的頭在進行插入排序
<pre class="cpp" name="code">#include"head.h"void sort_link(node_stu **head){//對鏈表進行排序node_stu *pre,*find_p,*original_p,*sort_p;//sort_p=(*head)->next->next;original_p=(*head)->next;//記錄原始字串的位置(*head)->next=NULL;//將頭結點next賦NULL,這個作為一個新的字串開始find_p=(*head);//找到位元組在新的字串中應該放的位置,與pre相對應,find_p在左,pre在右while(original_p!=NULL){//sort_p=original_p;//需要加入新的排序字串的節點original_p=original_p->next;//記錄原始字串的位置向後移sort_p->next=NULL;//將sort—p隔離出來find_p=(*head);//每次都從新的頭結點開始找int flag_mid=0;//標記在中間進行插入while(find_p->next!=NULL){//pre=find_p;//find_p=find_p->next;//pre 與find_p 一前一後,尋找插入值if((sort_p->num)>=(pre->num) && (sort_p->num)<=(find_p->num)){//flag_mid=1;//break;}}if(flag_mid!=1)//在頭插入或者在未插入find_p->next=sort_p;else {pre->next=sort_p;//在中間插入sort_p->next=find_p;}}}11)刪除鏈表中重複元素
<pre class="cpp" name="code">#include"head.h"void delete_repetition(node_stu** head){node_stu *end,*first,*temp;end=(*head)->next;first=end->next;while(first!=NULL){if(end->num==first->num){//遇到相同的就刪temp=end->next;end->next=first->next;first=first->next;delete (node_stu *) temp;}first=first->next;end=end->next;}}
12)判斷兩個鏈表是否有交點,並輸出交點
#include"head.h"int count_intersection(node_stu *head1,node_stu *head2,node_stu** node_intersection){int len1=0,len2=0,len;node_stu *p1,*p2;p1=head1;p2=head2;while(p1->next!=NULL){//計算p1有多長len1++;p1=p1->next;}while(p2->next!=NULL){//計算p2有多長len2++;p2=p2->next;}len=len1>len2?len2:len1;p1=head1;p2=head2;while(len--)//取最小值然後找到p1倒數len個節點是什麼p1=p1->next;while(p1->next!=NULL){p1=p1->next;head1=head1->next;}len=len1>len2?len2:len1;while(len--)//取最小值然後找到p2倒數len個節點是什麼p2=p2->next;while(p2->next!=NULL){p2=p2->next;head2=head2->next;}while(head1->next!=NULL){//在同時p1,p2為倒數len時,開始向後比較,看是否有交點head1=head1->next;head2=head2->next;if(head1==head2){*node_intersection=head1;//返回交點return 1;}}return 0;}
13)使兩個鏈表相交
#include"head.h"void make_intersection_link(node_stu** head1,node_stu** head2,int n,int m){//m新產生的,n是head1鏈表,輸入的n是想讓第n個節點為head1的交點,讓m為head2的交點node_stu *p,*p1;*head2=(node_stu *)calloc(1,sizeof(node_stu));p=*head2;p->next=NULL;for(int i=0;i<m;i++){p->next=(node_stu *)calloc(1,sizeof(node_stu));p=p->next;p->num=rand()%100;p->next=NULL;}p1=*head1;//這裡鏈表head1是之前就建好的while(n--)//將head1自增到n,p1=p1->next;p->next=p1;//然後與新產生的head2的第m個位置指向head1的第n個位置}
我寫的主函數用來測試各個函數
<pre class="cpp" name="code">#include"head.h"int main(int argc,char *argv[]){srand(time(NULL));node_stu *head=NULL;node_stu *head2=NULL;node_stu *head3=NULL;node_stu *node_intersection=NULL;int intersection_a,intersection_b;int size,n;while(~scanf("%d",&size)){//頭插發//link_init_tail(&head,size);//尾插法//link_init_head(&head,size);printf("插入後排序:\n");link_init_sort_insert(&head,size);//插入是排序cout<<endl;print_link(head);//列印字串printf("鏈表翻轉:\n");turn_link(&head);//鏈表翻轉print_link(head);//printf("輸出去倒數第幾個元素:");while(scanf("%d",&n),(n>size || n<=0))printf("輸入的數範圍不對,請重新輸入\n");//,printf("%d\n",find_back_num(head,n));//printf("輸出鏈表中間元素:\n");cout<<find_back_num(head)<<endl;//printf("輸出兩個字串:\n");print_link(head);link_init_head(&head2,size);///
print_link(head2);printf("合并之後:\n");unite_links(&head,&head2);//print_link(head);/***
//printf("判斷鏈表是否有環\n");//print_link(head2);//make_link_into_circle(&head2);//是鏈表編程有環鏈表//if(judge_circle(head2))//printf("有環\n");//else//printf("無環\n");*//*****/printf("將鏈表排序\n");sort_link(&head);print_link(head);/**/printf("重複資料刪除元素\n");delete_repetition(&head);/////////////////////////print_link(head);printf("判斷兩個鏈表是否有環,如果有輸出環\n");printf("製造兩個有交點的鏈表,輸入想讓head鏈表第幾個節點成為交點,同時新產生的鏈表第幾個成為交點;");scanf("%d %d",&intersection_a,&intersection_b);make_intersection_link(&head,&head2,intersection_a,intersection_b);//link_init_head(&head2,size);if(count_intersection(head,head2,&node_intersection)){printf("有\n");cout<<node_intersection->num<<endl;}else printf("無\n");}system("pause");}