一元多项式的表示及相加
1、一元多项式的表示:
一元多项式可按升幂的形式写成:
P
n
(
x
)
P_n(x)
Pn(x) =
p
0
p_0
p0 +
p
1
p_1
p1
x
1
x^1
x1 +
p
2
p_2
p2
x
2
x^2
x2 + … +
p
n
p_n
pn
x
n
x^n
xn,
P
i
P_i
Pi是指数i项的系数.
一元多项式
Q
m
(
x
)
Q_m(x)
Qm(x)可用线性表Q来表示.
Q= (
q
0
q_0
q0,
q
1
q_1
q1,
q
2
q_2
q2, …,
q
n
q_n
qn).
若m < n,则两个多项式相加的结果
R
n
(
x
)
R_n(x)
Rn(x)=
P
n
(
x
)
P_n(x)
Pn(x) +
Q
m
(
x
)
Q_m(x)
Qm(x),也可用线性表R来表示:
R=(
p
0
p_0
p0+
q
0
q_0
q0,
p
1
p_1
p1+
q
1
q_1
q1,…,
p
m
p_m
pm+
q
m
q_m
qm ,
p
m
+
1
p_{m+1}
pm+1,…,
p
n
p_n
pn).
2、一元多项式的存储
(1)一元多项式的顺序存储表示
法1:使用数组只存储多项式各项系数,系数对应的指数项则隐含在顺序表的下标中。
即p[0]存
x
0
x^0
x0的系数
p
0
p_0
p0,p[i]存
x
i
x^i
xi的系数
p
i
p_i
pi,……p[n]存
x
n
x^n
xn的系数
p
n
p_n
pn,下标即指数。
这种存储方法使得多项式相加运算的算法定义十分简单
只需将下标相同的单元的内容相加即可。
适合于存储表示非零系数多的多项式。
法2:只存储非零项。
每个非零项需要存储:系数和对应指数。
适合存储表示非零项少的多项式。
(2)一元多项式的链式存储表示
只存非零项:每项数据由两部分构成(指数项和系数项),外加指针项。
① 结点结构定义如下:
type struct Polynode
{
int coef;
int exp;
Polynode *next;
}Polynode,* Polylist
② 建立一元多项式链式存储的算法:
键盘输入一组多项式的系数和指数,输入系数0时结束,尾插法建链表,并按指数从小到大的顺序排列。
Polylist polycreate(Polylist head)
{
Polynode *rear,*s;
int c,e;
rear=head=(Polynode *)malloc(sizeof(Polynode)); //头结点,rear链尾
scanf("%d,%d",&c, &e); /*键入多项式的系数和指数项*/
while(c!=0) /*若c=0,则多项式输入结束*/
{
s = (Polynode *)malloc(sizeof(Polynode)); /*申请新结点*/
s->coef=c;
s->exp=e;
rear->next=s ; /*表尾插入*/
rear=s;
scanf("%d,%d", &c, &e);
}
rear->next = NULL; /*最后结点next置NULL*/
return(head);
}
③ 两个一元多项式相加
算法实现:p、q分别指向多项式链A、B第一结点,结果存到A链。
若p->exp < q->exp
:结点p应是“和多项式”中的一项,A链p后移;
若p->exp > q->exp
:结点q应是“和多项式”中的一项,将其插入p结点前,q在B链上后移;
若p->exp == q->exp
:两结点系数相加,和不为零则修改结点p的系数域,释放结点q;若和为零,则从A链中删去结点p,同时释放p和q结点。
void polyadd(Polylist polya; Polylist polyb) //合并polyb到polya中
{
Polynode *p, *q, *tail=polya;*temp; //新链尾
int sum;
p = polya->next;
q = polya->next;
while(p!=NULL && q!=NULL)
{ if(p->exp < q->exp) /*尾插结点p*/
{
tail->next = p;
tail = p;
p = p->next;
}
else if (p->exp == q->exp)//指数相等系数相加
{
if((sum = p->coef + q->coef) != 0)
{
p->coef = sum;
tail->next = p; //p系数更新
tail = p; p = p->next; //尾插p结点
temp = q; q = q->next;
free(temp);//删除q结点并后移
}
else /*系数和为零,则删除结点p与q,并移动p、q*/
{
temp=p; p=p->next; free(temp);
temp=q; q=q->next; free(temp);
}
else
{
tail->next=q; tail=q; q = q->next; /*将q结点加入到和多项式中*/
}
}
if(p!=NULL)
tail->next=p; /*A有剩余,加入到和多项式中*/
else
tail->next=q;
} /*将B剩余结点加入到和多项式中*/
顺序表 删除指定范围
题目:设计一个高效的算法,从顺序表L中删除所有值介于x和y之间(包括x和y)的所有元素(假设y>=x),要求时间复杂度为O(n),空间复杂度为O(1)。
struct _seqlist{
ElemType elem[MAXSIZE];
int last;
};
typedef struct _seqlist SeqList;
void del_x2y(SeqList* L, ElemType x, ElemType y)
{
int i = 0, j = 0;
for (i = 0; i < MAXSIZE; i++)
{
if (L->elem[i] < x || L->elem[i] > y)
L->elem[j++] = L->elem[i];
}
L->last=j;
}
顺序表 删除重复
编写算法,在一非递减的顺序表L中,删除所有值相等的多余元素。要求时间复杂度为O(n),空间复杂度为O(1)。
struct _seqlist{
ElemType elem[MAXSIZE];
int last;
};
typedef struct _seqlist SeqList;
void del_dupnum(SeqList* L)
{
int i = 0, j = 0;
ElemType demo = L->elem[0];
L->elem[j++] = L->elem[0];
for (i = 1; i < L->last; i++)
{
if (L->elem[i] != demo)
{
L->elem[j++] = L->elem[i];
demo = L->elem[i];
}
}
L->last = j;
}
顺序表 数据调整
已知顺序表L中的数据元素类型为int。设计算法将其调整为左右两部分,左边的元素(即排在前面的)均为奇数,右边所有元素(即排在后面的)均为偶数,并要求算法的时间复杂度为O(n),空间复杂度为O(1)。
struct _seqlist{
ElemType elem[MAXSIZE];
int last;
};
typedef struct _seqlist SeqList;
void odd_even(SeqList* L)
{
ElemType demo = L->elem[0];
int i = 1, temp, j = 0;
for (; i < L->last; i++)
{
j = i;
if (L->elem[i] % 2 != 0) //交换顺序
{
temp = L->elem[i];
L->elem[i] = demo;
demo = temp;
i = j;
}
}
}
链表 删除范围内结点
已知线性表中的元素(整数)以值递增有序排列,并以单链表作存储结构。试写一高效算法,删除表中所有大于mink且小于maxk的元素(若表中存在这样的元素),分析你的算法的时间复杂度。
struct _lnklist{
ElemType data;
struct _lnklist *next;
};
typedef struct _lnklist Node;
typedef struct _lnklist *LinkList;
void lnk_del_x2y(LinkList L, ElemType mink, ElemType maxk)
{
Node *pre, *r;
pre = L;
while (pre->next != NULL && pre->next->data <= mink) {
pre = pre->next;
}
while (pre->next != NULL && pre->next->data < maxk) {
r = pre->next;
pre->next = r->next;
free(r);
}
}
链表 倒数查找
已知一个带有表头结点的单链表, 假设链表只给出了头指针L。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,函数通过指针参数 p_ele 返回该结点 data 域的值,此时函数返回 1;否则,函数返回 0。
struct _lnklist{
ElemType data;
struct _lnklist *next;
};
typedef struct _lnklist Node;
typedef struct _lnklist *LinkList;
int lnk_search(LinkList L, int k, ElemType* p_ele)
{
Node *p, *r;
r = L;
p = L->next;
int i = 1;
while (p != NULL) {
p = p->next;
i++;
if (i > k) {//p和r之间的距离已经有k了,现在呢就要保持k的距离
r = r->next;
}
}
if (r == L) {
return 0;
} else {
*p_ele = r->data;
return 1;
}
}