將一串數字順序後移
一、題目描述
有n個整數,使前面各數順序向後移m個位置,最後m個數變成最前面m個數(m<n)。(歡迎訪問個人網站瀏覽此篇博文)
二、分析解答
這道題主要是編程邏輯的訓練。涉及到數組、指針的知識點,本道題目也能很好的表達出選用不同的數據結構,對同一道題目會有完全不同的解題思路,編程複雜度也會有很大的差別。
方法一:採用數組數據結構存儲數據。思路:①使用一個臨時數組,把原數組中的後m個數字先複製到這個新建的數組中,再把原數組中的元素向後移動m個位置,最後把臨時數組中的元素複製到原數組的開頭位置。②使用一個和原數組長度一樣的臨時數組,將原數組的後m個數字複製到臨時數組的前m位,然後再把原數組的剩餘的數字複製到臨時數組的後面,然後返回臨時數組。
值得注意的是思路①②的臨時數組空間大小是不一樣的,編程上略有區別。還要注意數組下標的計算,這點很容易出錯。
#include<stdio.h>
void shift(int *a,int n,int m)
{
int t[20];
int i;
for(i=0;i<n;i++)
{
t[i]=a[i];
}
for(i=0;i<m;i++)
{
a[i]=t[n-m+i];
}
for(i=m;i<n;i++)
{
a[i]=t[i-m];
}
}
int main()
{
int a[20];
int n,m;
int i;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
scanf("%d",&m);
shift(a,n,m);
for(i=0;i<n;i++)
{
printf("%d \t ",a[i]);
}
printf("\n");
return 0;
}
方法二:採用單鏈表數據結構存儲數據。思路:將第(N - M)位置的元素作爲首節點(也就是最後m個元素的首個元素節點),原鏈表首節點元素鏈接到原鏈表尾結點即可。
#include<stdio.h>
#include<stdlib.h>
typedef struct data_node{
int data;
struct data_node *next;
}Node;
int main(){
Node *head = NULL , *tail =NULL, *p = NULL;
int n,m,i=0;
//輸入N個整數
scanf("%d",&n);
while(i++<n){
//申請節點所佔用的內存空間
if( (p = (Node *)malloc(sizeof(Node))) == NULL){
printf("memery is not available");
exit(1);
}
scanf("%d", &(p->data));
p->next = NULL;
//當前申請的是第一個節點
if(head == NULL){
head = tail = p;
}else{
//鏈尾插值
tail->next = p;
tail = p;
}
}
//找到第(N-M)位置的前驅節點。
scanf("%d",&m);
i=0;
p = head;
while( i++<n -m -1){
p = p->next;
}
//注意這幾個元素的交換。是實現這個題目的核心所在
//最後m個元素的首元素作爲鏈頭,原鏈表首節點元素鏈接到原鏈表尾結點。這樣就實現了後移
tail->next = head;
head = p->next;
tail = p;
tail->next = NULL;
//輸出處理後的數
p = head;
while(p){
printf("%d ",p->data);
p = p->next;
}
printf("\n");
return 0;
}
程序運行結果示意圖:
三、小結
從上面的兩種不同的方法解決同一問題我們可以看到,不同數據結構的選擇,對編程思想的影響很大,數據結構的巧妙選擇有時會大大的簡化編程邏輯上的理解。同時,不同的數據結構還會對程序算法的時間複雜度和空間複雜度形成很大的差異。